integrator_runge_kutta.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 
41 
42 using namespace std;
43 
45 
46 
47 //
48 // PUBLIC MEMBER FUNCTIONS:
49 //
50 
52  :Integrator( ){
53 
55 }
56 
57 
58 IntegratorRK::IntegratorRK( int dim_ , double power_)
59  :Integrator( ){
60 
61  int run1;
62 
64  dim = dim_ ;
65  err_power = power_;
66 
67  // BUTCHER TABLEAU:
68  // ----------------
69  A = new double*[dim];
70  b4 = new double [dim];
71  b5 = new double [dim];
72  c = new double [dim];
73 
74  for( run1 = 0; run1 < dim; run1++ ){
75  A[run1] = new double[dim];
76  }
77 }
78 
79 
80 IntegratorRK::IntegratorRK( const DifferentialEquation& rhs_, int dim_, double power_ )
81  :Integrator( ){
82 
83  int run1;
84 
85  dim = dim_ ;
86  err_power = power_;
87 
88  // BUTCHER TABLEAU:
89  // ----------------
90  A = new double*[dim];
91  b4 = new double [dim];
92  b5 = new double [dim];
93  c = new double [dim];
94 
95  for( run1 = 0; run1 < dim; run1++ ){
96  A[run1] = new double[dim];
97  }
98 
99  init( rhs_ );
100 }
101 
102 
104  :Integrator( arg ){
105 
106  constructAll( arg );
107 }
108 
109 
111 
112  deleteAll();
113 }
114 
115 
117 
118  rhs = new DifferentialEquation( rhs_ );
119  m = rhs->getDim ();
120  ma = 0;
121  mn = rhs->getN ();
122  mu = rhs->getNU ();
123  mui = rhs->getNUI ();
124  mp = rhs->getNP ();
125  mpi = rhs->getNPI ();
126  mw = rhs->getNW ();
127 
128  allocateMemory();
129 
130  return SUCCESSFUL_RETURN;
131 }
132 
133 
135 
136  dim = 0; A = 0; b4 = 0; b5 = 0; c = 0;
137  eta4 = 0; eta5 = 0; eta4_ = 0; eta5_ = 0;
138  k = 0; k2 = 0; l = 0; l2 = 0; x = 0;
139 
140  G = 0; etaG = 0;
141  G2 = 0; G3 = 0; etaG2 = 0; etaG3 = 0;
142 
143  H = 0; etaH = 0; H2 = 0; H3 = 0;
144  etaH2 = 0; etaH3 = 0;
145 
146  maxAlloc = 0;
147  err_power = 1.0;
148 }
149 
150 
152 
153  int run1, run2;
154 
155  if( 0 != rhs->getNXA() ){
157  ASSERT(1 == 0);
158  }
159 
160  if( 0 != rhs->getNDX() ){
162  ASSERT(1 == 0);
163  }
164 
165 
166  if( m < 1 ){
168  ASSERT(1 == 0);
169  }
170 
171  // RK-ALGORITHM:
172  // -------------
173  eta4 = new double [m];
174  eta5 = new double [m];
175  eta4_ = new double [m];
176  eta5_ = new double [m];
177 
178  for( run1 = 0; run1 < m; run1++ ){
179 
180  eta4 [run1] = 0.0;
181  eta5 [run1] = 0.0;
182  eta4_[run1] = 0.0;
183  eta5_[run1] = 0.0;
184  }
185 
186  k = new double*[dim];
187  k2 = new double*[dim];
188  l = new double*[dim];
189  l2 = new double*[dim];
190  x = new double [rhs->getNumberOfVariables() + 1 + m];
191 
192  for( run1 = 0; run1 < rhs->getNumberOfVariables() + 1 + m; run1++ ){
193  x[run1] = 0.0;
194  }
195 
196  t = 0.0;
197 
198 
199  for( run1 = 0; run1 < dim; run1++ ){
200  k [run1] = new double[m];
201  k2 [run1] = new double[m];
202 
203  for( run2 = 0; run2 < m; run2++ ){
204  k [run1][run2] = 0.0;
205  k2[run1][run2] = 0.0;
206  }
207 
208  l [run1] = new double[rhs->getNumberOfVariables() + 1 + m];
209  l2 [run1] = new double[rhs->getNumberOfVariables() + 1 + m];
210 
211  for( run2 = 0; run2 < rhs->getNumberOfVariables() + 1 + m; run2++ ){
212  l [run1][run2] = 0.0;
213  l2[run1][run2] = 0.0;
214  }
215  }
216 
217  // INTERNAL INDEX LISTS:
218  // ---------------------
219  diff_index = new int[m];
220 
221  for( run1 = 0; run1 < m; run1++ ){
222  diff_index[run1] = rhs->getStateEnumerationIndex( run1 );
223  if( diff_index[run1] == rhs->getNumberOfVariables() ){
224  diff_index[run1] = diff_index[run1] + 1 + run1;
225  }
226  }
227 
228  control_index = new int[mu ];
229 
230  for( run1 = 0; run1 < mu; run1++ ){
231  control_index[run1] = rhs->index( VT_CONTROL, run1 );
232  }
233 
234  parameter_index = new int[mp ];
235 
236  for( run1 = 0; run1 < mp; run1++ ){
237  parameter_index[run1] = rhs->index( VT_PARAMETER, run1 );
238  }
239 
240  int_control_index = new int[mui];
241 
242  for( run1 = 0; run1 < mui; run1++ ){
243  int_control_index[run1] = rhs->index( VT_INTEGER_CONTROL, run1 );
244  }
245 
246  int_parameter_index = new int[mpi];
247 
248  for( run1 = 0; run1 < mpi; run1++ ){
250  }
251 
252  disturbance_index = new int[mw ];
253 
254  for( run1 = 0; run1 < mw; run1++ ){
255  disturbance_index[run1] = rhs->index( VT_DISTURBANCE, run1 );
256  }
257 
258  time_index = rhs->index( VT_TIME, 0 );
259 
260  diff_scale.init(m);
261  for( run1 = 0; run1 < m; run1++ )
262  diff_scale(run1) = rhs->scale( VT_DIFFERENTIAL_STATE, run1 );
263 
264 
265  // SENSITIVITIES:
266  // --------------
267  G = NULL;
268  etaG = NULL;
269 
270  G2 = NULL;
271  G3 = NULL;
272  etaG2 = NULL;
273  etaG3 = NULL;
274 
275  H = NULL;
276  etaH = NULL;
277 
278  H2 = NULL;
279  H3 = NULL;
280  etaH2 = NULL;
281  etaH3 = NULL;
282 
283 
284  // STORAGE:
285  // --------
286  maxAlloc = 1;
287 }
288 
289 
290 
292 
293  int run1;
294 
295 
296  // BUTCHER-
297  // TABLEAU:
298  // ----------
299  for( run1 = 0; run1 < dim; run1++ ){
300  delete[] A[run1];
301  }
302 
303  delete[] A;
304  delete[] b4;
305  delete[] b5;
306  delete[] c ;
307 
308 
309  // RK-ALGORITHM:
310  // -------------
311  if( eta4 != NULL ){
312  delete[] eta4;
313  }
314  if( eta4_ != NULL ){
315  delete[] eta4_;
316  }
317  if( eta5 != NULL ){
318  delete[] eta5;
319  }
320  if( eta5_ != NULL ){
321  delete[] eta5_;
322  }
323 
324  for( run1 = 0; run1 < dim; run1++ ){
325  if( k[run1] != NULL )
326  delete[] k[run1] ;
327  if( k2[run1] != NULL )
328  delete[] k2[run1];
329  if( l[run1] != NULL )
330  delete[] l[run1] ;
331  if( l2[run1] != NULL )
332  delete[] l2[run1];
333  }
334 
335  if( k != NULL )
336  delete[] k ;
337 
338  if( k2!= NULL )
339  delete[] k2;
340 
341  if( l != NULL )
342  delete[] l ;
343 
344  if( l2!= NULL )
345  delete[] l2;
346 
347  if( x != NULL )
348  delete[] x;
349 
350 
351  // SENSITIVITIES:
352  // ----------------------------------------
353 
354  if( G != NULL )
355  delete[] G;
356 
357  if( etaG != NULL )
358  delete[] etaG;
359 
360  if( G2 != NULL )
361  delete[] G2;
362 
363  if( G3 != NULL )
364  delete[] G3;
365 
366  if( etaG2 != NULL )
367  delete[] etaG2;
368 
369  if( etaG3 != NULL )
370  delete[] etaG3;
371 
372 
373  // ----------------------------------------
374 
375  if( H != NULL )
376  delete[] H;
377 
378  if( etaH != NULL )
379  delete[] etaH;
380 
381  if( H2 != NULL )
382  delete[] H2;
383 
384  if( H3 != NULL )
385  delete[] H3;
386 
387  if( etaH2 != NULL )
388  delete[] etaH2;
389 
390  if( etaH3 != NULL )
391  delete[] etaH3;
392 }
393 
394 
396 
397  if ( this != &arg ){
398  deleteAll();
399  Integrator::operator=( arg );
400  constructAll( arg );
401  }
402 
403  return *this;
404 }
405 
406 
408 
409  int run1, run2;
410 
411  rhs = new DifferentialEquation( *arg.rhs );
412 
413  m = arg.m ;
414  ma = arg.ma ;
415  mn = arg.mn ;
416  mu = arg.mu ;
417  mui = arg.mui ;
418  mp = arg.mp ;
419  mpi = arg.mpi ;
420  mw = arg.mw ;
421 
422 
423  if( m < 1 ){
425  ASSERT(1 == 0);
426  }
427 
428  // BUTCHER TABLEAU:
429  // ----------------
430  dim = arg.dim;
431  A = new double*[dim];
432  b4 = new double [dim];
433  b5 = new double [dim];
434  c = new double [dim];
435 
436  for( run1 = 0; run1 < dim; run1++ ){
437 
438  b4[run1] = arg.b4[run1];
439  b5[run1] = arg.b5[run1];
440  c [run1] = arg.c [run1];
441 
442  A[run1] = new double[dim];
443  for( run2 = 0; run2 < dim; run2++ )
444  A[run1][run2] = arg.A[run1][run2];
445  }
446 
447  // RK-ALGORITHM:
448  // -------------
449  eta4 = new double [m];
450  eta5 = new double [m];
451  eta4_ = new double [m];
452  eta5_ = new double [m];
453 
454  for( run1 = 0; run1 < m; run1++ ){
455 
456  eta4 [run1] = arg.eta4 [run1];
457  eta5 [run1] = arg.eta5 [run1];
458  eta4_[run1] = arg.eta4_[run1];
459  eta5_[run1] = arg.eta5_[run1];
460  }
461 
462  k = new double*[dim];
463  k2 = new double*[dim];
464  l = new double*[dim];
465  l2 = new double*[dim];
466  x = new double [rhs->getNumberOfVariables() + 1 + m];
467 
468  for( run1 = 0; run1 < rhs->getNumberOfVariables() + 1 + m; run1++ ){
469  x[run1] = arg.x[run1];
470  }
471 
472  t = arg.t;
473 
474 
475  for( run1 = 0; run1 < dim; run1++ ){
476  k [run1] = new double[m];
477  k2 [run1] = new double[m];
478 
479  for( run2 = 0; run2 < m; run2++ ){
480  k [run1][run2] = arg.k [run1][run2];
481  k2[run1][run2] = arg.k2[run1][run2];
482  }
483 
484  l [run1] = new double[rhs->getNumberOfVariables() + 1 + m];
485  l2 [run1] = new double[rhs->getNumberOfVariables() + 1 + m];
486 
487  for( run2 = 0; run2 < rhs->getNumberOfVariables() + 1 + m; run2++ ){
488  l [run1][run2] = arg.l [run1][run2];
489  l2[run1][run2] = arg.l2[run1][run2];
490  }
491  }
492 
493 
494  // SETTINGS:
495  // ---------
496  h = (double*)calloc(arg.maxAlloc,sizeof(double));
497  for( run1 = 0; run1 < arg.maxAlloc; run1++ ){
498  h[run1] = arg.h[run1];
499  }
500  hini = arg.hini;
501  hmin = arg.hmin;
502  hmax = arg.hmax;
503 
504  tune = arg.tune;
505  TOL = arg.TOL;
506 
507  err_power = arg.err_power;
508 
509 
510  // INTERNAL INDEX LISTS:
511  // ---------------------
512  diff_index = new int[m];
513 
514  for( run1 = 0; run1 < m; run1++ ){
515  diff_index[run1] = arg.diff_index[run1];
516  }
517 
518  ddiff_index = 0;
519  alg_index = 0;
520 
521  control_index = new int[mu ];
522 
523  for( run1 = 0; run1 < mu; run1++ ){
524  control_index[run1] = arg.control_index[run1];
525  }
526 
527  parameter_index = new int[mp ];
528 
529  for( run1 = 0; run1 < mp; run1++ ){
530  parameter_index[run1] = arg.parameter_index[run1];
531  }
532 
533  int_control_index = new int[mui];
534 
535  for( run1 = 0; run1 < mui; run1++ ){
536  int_control_index[run1] = arg.int_control_index[run1];
537  }
538 
539  int_parameter_index = new int[mpi];
540 
541  for( run1 = 0; run1 < mpi; run1++ ){
542  int_parameter_index[run1] = arg.int_parameter_index[run1];
543  }
544 
545  disturbance_index = new int[mw ];
546 
547  for( run1 = 0; run1 < mw; run1++ ){
548  disturbance_index[run1] = arg.disturbance_index[run1];
549  }
550 
551  time_index = arg.time_index;
552 
553 
554  // OTHERS:
555  // -------
557  count = arg.count ;
558  count2 = arg.count2 ;
559  count3 = arg.count3 ;
560 
561  diff_scale = arg.diff_scale;
562 
563 
564  // PRINT-LEVEL:
565  // ------------
566  PrintLevel = arg.PrintLevel;
567 
568 
569  // SENSITIVITIES:
570  // ---------------
571  nFDirs = 0 ;
572  nBDirs = 0 ;
573 
574  nFDirs2 = 0 ;
575  nBDirs2 = 0 ;
576 
577  G = NULL;
578  etaG = NULL;
579 
580  G2 = NULL;
581  G3 = NULL;
582  etaG2 = NULL;
583  etaG3 = NULL;
584 
585  H = NULL;
586  etaH = NULL;
587 
588  H2 = NULL;
589  H3 = NULL;
590  etaH2 = NULL;
591  etaH3 = NULL;
592 
593 
594  // THE STATE OF AGGREGATION:
595  // -------------------------
596  soa = arg.soa;
597 
598 
599  // STORAGE:
600  // --------
601  maxAlloc = arg.maxAlloc;
602 }
603 
604 
606 
607 
608  if( soa != SOA_UNFROZEN ){
609  if( PrintLevel != NONE ){
611  }
612  return RET_ALREADY_FROZEN;
613  }
614 
616  return SUCCESSFUL_RETURN;
617 }
618 
619 
620 
622 
623  if( soa != SOA_UNFROZEN ){
624  if( PrintLevel != NONE ){
626  }
627  return RET_ALREADY_FROZEN;
628  }
629 
631  return SUCCESSFUL_RETURN;
632 }
633 
634 
636 
637  maxAlloc = 1;
638  h = (double*)realloc(h,maxAlloc*sizeof(double));
639  soa = SOA_UNFROZEN;
640 
641  return SUCCESSFUL_RETURN;
642 }
643 
644 
646  const DVector &xa ,
647  const DVector &p ,
648  const DVector &u ,
649  const DVector &w ,
650  const Grid &t_ ){
651 
652  int run1;
653  returnValue returnvalue;
654 
655  if( rhs == NULL ){
656  return ACADOERROR(RET_TRIVIAL_RHS);
657  }
658 
659  if( xa.getDim() != 0 )
661 
662 
664 
665  timeInterval = t_;
666 
669 
672 // printf("initial integrator t = %e\n", t );
673 // printf("initial integrator x[time_index] = %e\n", x[time_index] );
674 // printf(" with time_index = %d\n", time_index );
675 
677  h[0] = hini;
678 
681 
682  if( h[0] < 10.0*EPS )
684  }
685  }
686 
687  if( x0.isEmpty() == BT_TRUE ) return ACADOERROR(RET_MISSING_INPUTS);
688 
689 
690  if( (int) x0.getDim() < m )
692 
693  for( run1 = 0; run1 < m; run1++ ){
694  eta4[run1] = x0(run1);
695  eta5[run1] = x0(run1);
696  xStore(0,run1) = x0(run1);
697  }
698 
699  if( nFDirs != 0 ){
700  for( run1 = 0; run1 < m; run1++ ){
701  etaG[run1] = fseed(diff_index[run1]);
702  }
703  }
704 
705  if( mp > 0 ){
706  if( (int) p.getDim() < mp )
708 
709  for( run1 = 0; run1 < mp; run1++ ){
710  x[parameter_index[run1]] = p(run1);
711  }
712  }
713 
714  if( mu > 0 ){
715  if( (int) u.getDim() < mu )
717 
718  for( run1 = 0; run1 < mu; run1++ ){
719  x[control_index[run1]] = u(run1);
720  }
721  }
722 
723 
724  if( mw > 0 ){
725  if( (int) w.getDim() < mw )
727 
728  for( run1 = 0; run1 < mw; run1++ ){
729  x[disturbance_index[run1]] = w(run1);
730  }
731  }
732 
733 
734  totalTime.start();
735  nFcnEvaluations = 0;
736 
737 
738  // Initialize the scaling based on the initial states:
739  // ---------------------------------------------------
740 
741  double atol;
742  get( ABSOLUTE_TOLERANCE, atol );
743 
744  for( run1 = 0; run1 < m; run1++ )
745  diff_scale(run1) = fabs(eta4[run1]) + atol/TOL;
746 
747 
748  // PRINTING:
749  // ---------
750  if( PrintLevel == HIGH || PrintLevel == MEDIUM ){
751  acadoPrintCopyrightNotice( "IntegratorRK -- A Runge Kutta integrator." );
752  }
753  if( PrintLevel == HIGH ){
754  cout << "RK: t = " << t << "\t";
755  for( run1 = 0; run1 < m; run1++ )
756  cout << "x[" << run1 << "] = " << scientific << eta4[ run1 ];
757  cout << endl;
758  }
759 
760 
761  returnvalue = RET_FINAL_STEP_NOT_PERFORMED_YET;
762 
763  count3 = 0;
764  count = 1;
765 
766  while( returnvalue == RET_FINAL_STEP_NOT_PERFORMED_YET && count <= maxNumberOfSteps ){
767 
768  returnvalue = step(count);
769  count++;
770  }
771 
772  count2 = count-1;
773 
774  for( run1 = 0; run1 < mn; run1++ )
775  iStore( 0, run1 ) = iStore( 1, run1 );
776 
777  totalTime.stop();
778 
779  if( count > maxNumberOfSteps ){
780  if( PrintLevel != NONE )
783  }
784 
785 
786 // cout << "numIntSteps = %d\n",count-1);
787 
788 
789  // SET THE LOGGING INFORMATION:
790  // ----------------------------------------------------------------------------------------
791 
800 
801  // ----------------------------------------------------------------------------------------
802 
803 
804  // PRINTING:
805  // ---------
806  if( PrintLevel == MEDIUM ){
807 
808  if( soa == SOA_EVERYTHING_FROZEN ){
809  cout << "\n Results at t = " << t << "\t";
810  for( run1 = 0; run1 < m; run1++ )
811  cout << "x[" << run1 << "] = " << scientific << eta4[ run1 ];
812  cout << endl;
813  }
815  }
816 
817  int printIntegratorProfile = 0;
818  get( PRINT_INTEGRATOR_PROFILE,printIntegratorProfile );
819 
820  if ( (BooleanType)printIntegratorProfile == BT_TRUE )
821  {
823  }
824  else
825  {
826  if( PrintLevel == MEDIUM || PrintLevel == HIGH )
827  cout << "RK: number of steps: " << count - 1 << endl;
828  }
829 
830  return returnvalue;
831 }
832 
833 
834 
836  const DVector &pSeed,
837  const DVector &uSeed,
838  const DVector &wSeed,
839  const int &order ){
840 
841  if( order == 2 ){
842  return setForwardSeed2( xSeed, pSeed, uSeed, wSeed);
843  }
844  if( order < 1 || order > 2 ){
846  }
847 
848  if( nBDirs > 0 ){
850  }
851 
852  int run2;
853 
854  if( G != NULL ){
855  delete[] G;
856  G = NULL;
857  }
858 
859  if( etaG != NULL ){
860  delete[] etaG;
861  etaG = NULL;
862  }
863 
864  nFDirs = 1;
865 
867  fseed.setZero();
868 
869  G = new double[rhs->getNumberOfVariables() + 1 + m];
870 
871  for( run2 = 0; run2 < (rhs->getNumberOfVariables()+1+m); run2++ ){
872  G[run2] = 0.0;
873  }
874 
875  etaG = new double[m];
876 
877  if( xSeed.getDim() != 0 ){
878  for( run2 = 0; run2 < m; run2++ ){
879  fseed(diff_index[run2]) = xSeed(run2);
880  }
881  }
882 
883  if( pSeed.getDim() != 0 ){
884  for( run2 = 0; run2 < mp; run2++ ){
885  fseed(parameter_index[run2]) = pSeed(run2);
886  G [parameter_index[run2]] = pSeed(run2);
887  }
888  }
889 
890  if( uSeed.getDim() != 0 ){
891  for( run2 = 0; run2 < mu; run2++ ){
892  fseed(control_index[run2]) = uSeed(run2);
893  G [control_index[run2]] = uSeed(run2);
894  }
895  }
896 
897  if( wSeed.getDim() != 0 ){
898 
899  for( run2 = 0; run2 < mw; run2++ ){
900  fseed(disturbance_index[run2]) = wSeed(run2);
901  G[disturbance_index[run2]] = wSeed(run2);
902  }
903  }
904 
905  return SUCCESSFUL_RETURN;
906 }
907 
908 
910  const DVector &pSeed ,
911  const DVector &uSeed ,
912  const DVector &wSeed ){
913 
914  int run2;
915 
916  if( G2 != NULL ){
917  delete[] G2;
918  G2 = NULL;
919  }
920 
921  if( G3 != NULL ){
922  delete[] G3;
923  G3 = NULL;
924  }
925 
926  if( etaG2 != NULL ){
927  delete[] etaG2;
928  etaG2 = NULL;
929  }
930 
931  if( etaG3 != NULL ){
932  delete[] etaG3;
933  etaG3 = NULL;
934  }
935 
936  nFDirs2 = 1;
937 
939  fseed2.setZero();
940 
941  G2 = new double[rhs->getNumberOfVariables() + 1 + m];
942  G3 = new double[rhs->getNumberOfVariables() + 1 + m];
943 
944  for( run2 = 0; run2 < (rhs->getNumberOfVariables()+1+m); run2++ ){
945  G2[run2] = 0.0;
946  G3[run2] = 0.0;
947  }
948  etaG2 = new double[m];
949  etaG3 = new double[m];
950 
951  if( xSeed.getDim() != 0 ){
952  for( run2 = 0; run2 < m; run2++ ){
953  fseed2(diff_index[run2]) = xSeed(run2);
954  }
955  }
956 
957  if( pSeed.getDim() != 0 ){
958  for( run2 = 0; run2 < mp; run2++ ){
959  fseed2(parameter_index[run2]) = pSeed(run2);
960  G2 [parameter_index[run2]] = pSeed(run2);
961  }
962  }
963 
964  if( uSeed.getDim() != 0 ){
965  for( run2 = 0; run2 < mu; run2++ ){
966  fseed2(control_index[run2]) = uSeed(run2);
967  G2 [control_index[run2]] = uSeed(run2);
968  }
969  }
970 
971  if( wSeed.getDim() != 0 ){
972  for( run2 = 0; run2 < mw; run2++ ){
973  fseed2(disturbance_index[run2]) = wSeed(run2);
974  G2 [disturbance_index[run2]] = wSeed(run2);
975  }
976  }
977  return SUCCESSFUL_RETURN;
978 }
979 
980 
982 
983  if( order == 2 ){
984  return setBackwardSeed2(seed);
985  }
986  if( order < 1 || order > 2 ){
988  }
989 
990  if( nFDirs > 0 ){
992  }
993 
994  int run2;
995 
996  if( H != NULL ){
997  delete[] H;
998  H = NULL;
999  }
1000 
1001  if( etaH != NULL ){
1002  delete[] etaH;
1003  etaH = NULL;
1004  }
1005 
1006  nBDirs = 1;
1007 
1008  bseed.init( m );
1009  bseed.setZero();
1010 
1011  H = new double[m];
1012 
1013  etaH = new double[rhs->getNumberOfVariables()+1+m];
1014  for( run2 = 0; run2 < rhs->getNumberOfVariables()+1+m; run2++ ){
1015  etaH[run2] = 0.0;
1016  }
1017 
1018  if( seed.getDim() != 0 ){
1019  for( run2 = 0; run2 < m; run2++ ){
1020  bseed(run2) = seed(run2);
1021  }
1022  }
1023 
1024  return SUCCESSFUL_RETURN;
1025 }
1026 
1027 
1028 
1030 
1031  int run2;
1032 
1033  if( H2 != NULL ){
1034  delete[] H2;
1035  H2 = NULL;
1036  }
1037 
1038  if( H3 != NULL ){
1039  delete[] H3;
1040  H3 = NULL;
1041  }
1042 
1043  if( etaH2 != NULL ){
1044  delete[] etaH2;
1045  etaH2 = NULL;
1046  }
1047 
1048  if( etaH3 != NULL ){
1049  delete[] etaH3;
1050  etaH3 = NULL;
1051  }
1052 
1053 
1054  nBDirs2 = 1;
1055 
1056  bseed2.init(m);
1057  bseed2.setZero();
1058 
1059  H2 = new double[m];
1060  H3 = new double[m];
1061 
1062  etaH2 = new double[rhs->getNumberOfVariables()+1+m];
1063  etaH3 = new double[rhs->getNumberOfVariables()+1+m];
1064 
1065  if( seed.getDim() != 0 ){
1066  for( run2 = 0; run2 < m; run2++ ){
1067  bseed2(run2) = seed(run2);
1068  }
1069  }
1070 
1071  return SUCCESSFUL_RETURN;
1072 }
1073 
1074 
1076 
1077  int run1, run2 ;
1078  returnValue returnvalue;
1079 
1080  if( rhs == NULL ){
1081  return ACADOERROR(RET_TRIVIAL_RHS);
1082  }
1083 
1084  if( soa != SOA_EVERYTHING_FROZEN ){
1085  return ACADOERROR(RET_NOT_FROZEN);
1086  }
1087 
1088 
1089  if( nFDirs != 0 ){
1091  dxStore.init( m, timeInterval );
1092  for( run1 = 0; run1 < m; run1++ ){
1093  etaG[run1] = fseed(diff_index[run1]);
1094  }
1095  }
1096 
1097  if( nBDirs != 0 ){
1098  for( run2 = 0; run2 < (rhs->getNumberOfVariables()+1+m); run2++){
1099  etaH[run2] = 0.0;
1100  }
1101  }
1102 
1103  if( nBDirs != 0 ){
1104  for( run1 = 0; run1 < m; run1++ ){
1105  etaH[diff_index[run1]] = bseed(run1);
1106  }
1107  }
1108 
1109  if( nFDirs2 != 0 ){
1112  for( run1 = 0; run1 < m; run1++ ){
1113  etaG2[run1] = fseed2(diff_index[run1]);
1114  etaG3[run1] = 0.0;
1115  }
1116  }
1117 
1118  if( nBDirs2 != 0 ){
1119  for( run2 = 0; run2 < (rhs->getNumberOfVariables()+1+m); run2++){
1120  etaH2[run2] = 0.0;
1121  etaH3[run2] = 0.0;
1122  }
1123  }
1124 
1125  if( nBDirs2 != 0 ){
1126  for( run1 = 0; run1 < m; run1++ ){
1127  etaH2[diff_index[run1]] = bseed2(run1);
1128  }
1129  }
1130 
1131  if( PrintLevel == HIGH ){
1133  }
1134 
1135  returnvalue = RET_FINAL_STEP_NOT_PERFORMED_YET;
1136 
1137 
1138  if( nBDirs > 0 || nBDirs2 > 0 ){
1139 
1140  int oldCount = count;
1141 
1142  count--;
1143  while( returnvalue == RET_FINAL_STEP_NOT_PERFORMED_YET && count >= 1 ){
1144 
1145  returnvalue = step( count );
1146  count--;
1147  }
1148 
1149  if( count == 0 && (returnvalue == RET_FINAL_STEP_NOT_PERFORMED_YET ||
1150  returnvalue == SUCCESSFUL_RETURN ) ){
1151 
1152 
1153  if( PrintLevel == MEDIUM ){
1155  }
1156  count = oldCount;
1157 
1158  return SUCCESSFUL_RETURN;
1159  }
1160  count = oldCount;
1161  }
1162  else{
1163 
1164  count = 1;
1165  while( returnvalue == RET_FINAL_STEP_NOT_PERFORMED_YET &&
1166  count <= maxNumberOfSteps ){
1167 
1168  returnvalue = step(count);
1169  count++;
1170  }
1171 
1172  if( nBDirs2 == 0 && nFDirs != 0 )
1173  for( run1 = 0; run1 < m; run1++ )
1174  dxStore( 0, run1 ) = dxStore( 1, run1 );
1175 
1176  if( nFDirs2 != 0 )
1177  for( run1 = 0; run1 < m; run1++ )
1178  ddxStore( 0, run1 ) = ddxStore( 1, run1 );
1179 
1180  if( count > maxNumberOfSteps ){
1181  if( PrintLevel != NONE )
1184  }
1185 
1186  if( PrintLevel == MEDIUM ){
1188  }
1189  }
1190  return returnvalue;
1191 }
1192 
1193 
1195 
1196  int run1;
1197  double E = EPS;
1198 
1200  h[0] = h[number_];
1201  }
1202 
1203  if( soa == SOA_FREEZING_MESH ||
1204  soa == SOA_MESH_FROZEN ||
1206  soa == SOA_UNFROZEN ){
1207 
1208  if( nFDirs > 0 ){
1209  E = determineEta45(0);
1210  }
1211  else{
1212  E = determineEta45();
1213  }
1214  }
1215  if( soa == SOA_FREEZING_ALL ){
1216  E = determineEta45(dim*number_);
1217  }
1218 
1219 
1221 
1222  int number_of_rejected_steps = 0;
1223 
1224  if( E < 0.0 ){
1226  }
1227 
1228  // REJECT THE STEP IF GIVEN TOLERANCE IS NOT ACHIEVED:
1229  // ---------------------------------------------------
1230  while( E >= TOL*h[0] ){
1231 
1232  if( PrintLevel == HIGH ){
1233  cout << "STEP REJECTED: error estimate = " << scientific << E << endl
1234  << " required local tolerance = " << TOL*h[0] << endl;
1235  }
1236 
1237  number_of_rejected_steps++;
1238 
1239  for( run1 = 0; run1 < m; run1++ ){
1240  eta4[run1] = eta4_[run1];
1241  }
1242  if( h[0] <= hmin + EPS ){
1244  }
1245  h[0] = 0.5*h[0];
1246  if( h[0] < hmin ){
1247  h[0] = hmin;
1248  }
1249 
1250  if( soa == SOA_FREEZING_MESH ||
1251  soa == SOA_UNFROZEN ){
1252 
1253  if( nFDirs > 0 ){
1254  E = determineEta45(0);
1255  }
1256  else{
1257  E = determineEta45();
1258  }
1259  }
1260  if( soa == SOA_FREEZING_ALL ){
1261  E = determineEta45(dim*number_);
1262  }
1263 
1264  if( E < 0.0 ){
1266  }
1267  }
1268 
1269  count3 += number_of_rejected_steps;
1270  }
1271 
1272  // PROCEED IF THE STEP IS ACCEPTED:
1273  // --------------------------------
1274 
1275  double *etaG_ = new double[m];
1276  double *etaG3_ = new double[m];
1277 
1278 
1279  // compute forward derivatives if requested:
1280  // ------------------------------------------
1281 
1282  if( nFDirs > 0 && nBDirs2 == 0 && nFDirs2 == 0 ){
1283 
1284  for( run1 = 0; run1 < m; run1++ )
1285  etaG_[run1] = etaG[run1];
1286 
1287  if( nBDirs != 0 ){
1289  }
1290 
1292  determineEtaGForward(dim*number_);
1293  }
1294  else{
1296  }
1297  }
1298  if( nBDirs > 0 ){
1299 
1300  if( soa != SOA_EVERYTHING_FROZEN ){
1301  return ACADOERROR(RET_NOT_FROZEN);
1302  }
1303  if( nFDirs != 0 || nBDirs2 != 0 || nFDirs2 != 0 ){
1305  }
1306  determineEtaHBackward(dim*number_);
1307  }
1308  if( nFDirs2 > 0 ){
1309 
1310  for( run1 = 0; run1 < m; run1++ )
1311  etaG3_[run1] = etaG3[run1];
1312 
1313  if( soa != SOA_EVERYTHING_FROZEN ){
1314  return ACADOERROR(RET_NOT_FROZEN);
1315  }
1316  if( nBDirs != 0 || nBDirs2 != 0 || nFDirs != 1 ){
1318  }
1319  determineEtaGForward2(dim*number_);
1320  }
1321  if( nBDirs2 > 0 ){
1322 
1323  if( soa != SOA_EVERYTHING_FROZEN ){
1324  return ACADOERROR(RET_NOT_FROZEN);
1325  }
1326  if( nBDirs != 0 || nFDirs2 != 0 || nFDirs != 1 ){
1328  }
1329 
1330  determineEtaHBackward2(dim*number_);
1331  }
1332 
1333 
1334  // increase the time:
1335  // ----------------------------------------------
1336 
1337  if( nBDirs > 0 || nBDirs2 > 0 ){
1338 
1339  t = t - h[0];
1340  }
1341  else{
1342 
1343  t = t + h[0];
1344  }
1345 // printf("t = %e\n",t );
1346 
1347  // PRINTING:
1348  // ---------
1349  if( PrintLevel == HIGH ){
1350  cout << "RK: t = " << scientific << t << " h = " << h[ 0 ] << " ";
1352  }
1353 
1354 
1355  // STORAGE:
1356  // --------
1357 
1359 
1360  if( number_ >= maxAlloc){
1361 
1362  maxAlloc = 2*maxAlloc;
1363  h = (double*)realloc(h,maxAlloc*sizeof(double));
1364  }
1365  h[number_] = h[0];
1366  }
1367 
1368  int i1 = timeInterval.getFloorIndex( t-h[0] );
1369  int i2 = timeInterval.getFloorIndex( t );
1370  int jj;
1371 
1372  for( jj = i1+1; jj <= i2; jj++ ){
1373 
1374  if( nFDirs == 0 && nBDirs == 0 && nFDirs2 == 0 && nBDirs == 0 ) interpolate( jj, eta4_ , k[0], eta4 , xStore );
1375  if( nFDirs > 0 && nBDirs2 == 0 && nFDirs2 == 0 ) interpolate( jj, etaG_ , k[0], etaG , dxStore );
1376  if( nFDirs2 > 0 ) interpolate( jj, etaG3_, k[0], etaG3, ddxStore );
1377 
1378  for( run1 = 0; run1 < mn; run1++ )
1379  iStore( jj, run1 ) = x[rhs->index( VT_INTERMEDIATE_STATE, run1 )];
1380  }
1381 
1382  delete[] etaG_ ;
1383  delete[] etaG3_;
1384 
1385 
1386  if( nBDirs == 0 || nBDirs2 == 0 ){
1387 
1388  // Stop the algorithm if t >= te:
1389  // ----------------------------------------------
1390  if( t >= timeInterval.getLastTime() - EPS ){
1392  for( run1 = 0; run1 < m; run1++ ){
1393  if ( acadoIsNaN( eta4[run1] ) == BT_TRUE )
1395  x[diff_index[run1]] = eta4[run1];
1396  }
1397 
1398  if( soa == SOA_FREEZING_MESH ){
1399  soa = SOA_MESH_FROZEN;
1400  }
1403  }
1404 
1405  return SUCCESSFUL_RETURN;
1406  }
1407  }
1408 
1409 
1411 
1412 
1413  // recompute the scaling based on the actual states:
1414  // -------------------------------------------------
1415 
1416  double atol;
1417  get( ABSOLUTE_TOLERANCE, atol );
1418 
1419  for( run1 = 0; run1 < m; run1++ )
1420  diff_scale(run1) = fabs(eta4[run1]) + atol/TOL;
1421 
1422 
1423 
1424  // apply a numeric stabilization of the step size control:
1425  // -------------------------------------------------------
1426  double Emin = 1e-3*sqrt(TOL)*pow(hini, ((1.0/err_power)+1.0)/2.0 );
1427 
1428  if( E < Emin ) E = Emin ;
1429  if( E < 10.0*EPS ) E = 10.0*EPS;
1430 
1431 
1432  // determine the new step size:
1433  // ----------------------------------------------
1434  h[0] = h[0]*pow( tune*(TOL*h[0]/E), err_power );
1435 
1436  if( h[0] > hmax ){
1437  h[0] = hmax;
1438  }
1439  if( h[0] < hmin ){
1440  h[0] = hmin;
1441  }
1442 
1443  if( t + h[0] >= timeInterval.getLastTime() ){
1444  h[0] = timeInterval.getLastTime()-t;
1445  }
1446 
1447 // printf( "t = %e, stepsize = %e\n", t,h[0] );
1448  }
1449 
1451 }
1452 
1453 
1454 
1456 
1458 }
1459 
1460 
1462 
1463  int run1;
1464 
1465  if( (int) xEnd[0].getDim() != m )
1467 
1468  for( run1 = 0; run1 < m; run1++ )
1469  xEnd[0](run1) = eta4[run1];
1470 
1471  return SUCCESSFUL_RETURN;
1472 }
1473 
1474 
1476 
1477  int run1;
1478 
1479  if( Dx == NULL ){
1480  return SUCCESSFUL_RETURN;
1481  }
1482 
1483  if( order == 1 && nFDirs2 == 0 ){
1484  for( run1 = 0; run1 < m; run1++ ){
1485  Dx[0](run1,0) = etaG[run1];
1486  }
1487  }
1488 
1489  if( order == 2 ){
1490  for( run1 = 0; run1 < m; run1++ ){
1491  Dx[0](run1,0) = etaG3[run1];
1492  }
1493  }
1494 
1495  if( order == 1 && nFDirs2 > 0 ){
1496  for( run1 = 0; run1 < m; run1++ ){
1497  Dx[0](run1,0) = etaG2[run1];
1498  }
1499  }
1500 
1501  if( order < 1 || order > 2 ){
1503  }
1504 
1505  return SUCCESSFUL_RETURN;
1506 }
1507 
1508 
1510  DVector &Dx_p ,
1511  DVector &Dx_u ,
1512  DVector &Dx_w ,
1513  int order ) const{
1514 
1515  int run2;
1516 
1517  if( order == 1 && nBDirs2 == 0 ){
1518 
1519  if( Dx_x0.getDim() != 0 ){
1520  for( run2 = 0; run2 < m; run2++ )
1521  Dx_x0(run2) = etaH[diff_index[run2]];
1522  }
1523  if( Dx_p.getDim() != 0 ){
1524  for( run2 = 0; run2 < mp; run2++ ){
1525  Dx_p(run2) = etaH[parameter_index[run2]];
1526  }
1527  }
1528  if( Dx_u.getDim() != 0 ){
1529  for( run2 = 0; run2 < mu; run2++ ){
1530  Dx_u(run2) = etaH[control_index[run2]];
1531  }
1532  }
1533  if( Dx_w.getDim() != 0 ){
1534  for( run2 = 0; run2 < mw; run2++ ){
1535  Dx_w(run2) = etaH[disturbance_index[run2]];
1536  }
1537  }
1538  }
1539 
1540  if( order == 1 && nBDirs2 > 0 ){
1541 
1542  if( Dx_x0.getDim() != 0 ){
1543  for( run2 = 0; run2 < m; run2++ ){
1544  Dx_x0(run2) = etaH2[diff_index[run2]];
1545  }
1546  }
1547  if( Dx_u.getDim() != 0 ){
1548  for( run2 = 0; run2 < mu; run2++ ){
1549  Dx_u(run2) = etaH2[control_index[run2]];
1550  }
1551  }
1552  if( Dx_p.getDim() != 0 ){
1553  for( run2 = 0; run2 < mp; run2++ ){
1554  Dx_p(run2) = etaH2[parameter_index[run2]];
1555  }
1556  }
1557  if( Dx_w.getDim() != 0 ){
1558  for( run2 = 0; run2 < mw; run2++ ){
1559  Dx_w(run2) = etaH2[disturbance_index[run2]];
1560  }
1561  }
1562  }
1563 
1564 
1565  if( order == 2 ){
1566 
1567  if( Dx_x0.getDim() != 0 ){
1568  for( run2 = 0; run2 < m; run2++ ){
1569  Dx_x0(run2) = etaH3[diff_index[run2] ];
1570  }
1571  }
1572  if( Dx_u.getDim() != 0 ){
1573  for( run2 = 0; run2 < mu; run2++ ){
1574  Dx_u(run2) = etaH3[control_index[run2]];
1575  }
1576  }
1577  if( Dx_p.getDim() != 0 ){
1578  for( run2 = 0; run2 < mp; run2++ ){
1579  Dx_p(run2) = etaH3[parameter_index[run2]];
1580  }
1581  }
1582  if( Dx_w.getDim() != 0 ){
1583  for( run2 = 0; run2 < mw; run2++ ){
1584  Dx_w(run2) = etaH3[disturbance_index[run2]];
1585  }
1586  }
1587  }
1588 
1589  if( order < 1 || order > 2 ){
1590 
1592  }
1593 
1594  return SUCCESSFUL_RETURN;
1595 }
1596 
1597 
1599 
1600  return count2;
1601 }
1602 
1604 
1605  return count3;
1606 }
1607 
1608 
1610 
1611  return h[0];
1612 }
1613 
1614 
1616 
1617  return SUCCESSFUL_RETURN;
1618 }
1619 
1620 //
1621 // PROTECTED MEMBER FUNCTIONS:
1622 //
1623 
1624 
1626 
1627  int run1, run2, run3;
1628  double E;
1629 
1630  // determine k:
1631  // -----------------------------------------------
1632  for( run1 = 0; run1 < dim; run1++ ){
1633  x[time_index] = t + c[run1]*h[0];
1634  for( run2 = 0; run2 < m; run2++ ){
1635  x[diff_index[run2]] = eta4[run2];
1636  for( run3 = 0; run3 < run1; run3++ ){
1637  x[diff_index[run2]] = x[diff_index[run2]] +
1638  A[run1][run3]*h[0]*k[run3][run2];
1639  }
1640  }
1642 
1643  if( rhs[0].evaluate( 0, x, k[run1] ) != SUCCESSFUL_RETURN ){
1645  return -1.0;
1646  }
1647 
1649  nFcnEvaluations++;
1650  }
1651 
1652  // save previous eta4:
1653  // ----------------------------------------------
1654 
1655  for( run1 = 0; run1 < m; run1++ ){
1656  eta4_[run1] = eta4[run1];
1657  eta5 [run1] = eta4[run1]; // TODO: check if eta4 is correct here!?
1658  //printf( "%e\n",eta4[run1] );
1659  }
1660 
1661  // determine eta4 and eta5:
1662  // ----------------------------------------------
1663 
1664  for( run1 = 0; run1 < dim; run1++ ){
1665  for( run2 = 0; run2 < m; run2++ ){
1666  eta4[run2] = eta4[run2] + b4[run1]*h[0]*k[run1][run2];
1667  eta5[run2] = eta5[run2] + b5[run1]*h[0]*k[run1][run2];
1668  }
1669  }
1670 
1671  // determine local error estimate E:
1672  // ----------------------------------------------
1673 
1674  E = EPS;
1675  for( run2 = 0; run2 < m; run2++ ){
1676  if( (eta4[run2]-eta5[run2])/diff_scale(run2) >= E ){
1677  E = (eta4[run2]-eta5[run2])/diff_scale(run2);
1678  }
1679  if( (eta4[run2]-eta5[run2])/diff_scale(run2) <= -E ){
1680  E = (-eta4[run2]+eta5[run2])/diff_scale(run2);
1681  }
1682  }
1683 
1684  return E;
1685 }
1686 
1687 
1688 
1689 double IntegratorRK::determineEta45( int number_ ){
1690 
1691  int run1, run2, run3;
1692  double E;
1693 
1694  // determine k:
1695  // -----------------------------------------------
1696  for( run1 = 0; run1 < dim; run1++ ){
1697  x[time_index] = t + c[run1]*h[0];
1698  for( run2 = 0; run2 < m; run2++ ){
1699  x[diff_index[run2]] = eta4[run2];
1700  for( run3 = 0; run3 < run1; run3++ ){
1701  x[diff_index[run2]] = x[diff_index[run2]] +
1702  A[run1][run3]*h[0]*k[run3][run2];
1703  }
1704  }
1706 
1707  if( rhs[0].evaluate( number_+run1, x, k[run1] ) != SUCCESSFUL_RETURN ){
1709  return -1.0;
1710  }
1711 
1713  nFcnEvaluations++;
1714  }
1715 
1716  // save previous eta4:
1717  // ----------------------------------------------
1718 
1719  for( run1 = 0; run1 < m; run1++ ){
1720  eta4_[run1] = eta4[run1];
1721  eta5 [run1] = eta4[run1];
1722  }
1723 
1724  // determine eta4 and eta5:
1725  // ----------------------------------------------
1726  for( run1 = 0; run1 < dim; run1++ ){
1727  for( run2 = 0; run2 < m; run2++ ){
1728  eta4[run2] = eta4[run2] + b4[run1]*h[0]*k[run1][run2];
1729  eta5[run2] = eta5[run2] + b5[run1]*h[0]*k[run1][run2];
1730  }
1731  }
1732 
1733  // determine local error estimate E:
1734  // ----------------------------------------------
1735 
1736  E = EPS;
1737  for( run2 = 0; run2 < m; run2++ ){
1738  if( (eta4[run2]-eta5[run2])/diff_scale(run2) >= E )
1739  E = (eta4[run2]-eta5[run2])/diff_scale(run2);
1740  if( (eta4[run2]-eta5[run2])/diff_scale(run2) <= -E )
1741  E = (-eta4[run2]+eta5[run2])/diff_scale(run2);
1742  }
1743 
1744  return E;
1745 }
1746 
1747 
1749 
1750  int run1, run2, run3;
1751 
1752  // determine k:
1753  // -----------------------------------------------
1754  for( run1 = 0; run1 < dim; run1++ ){
1755  for( run2 = 0; run2 < m; run2++ ){
1756  G[diff_index[run2]] = etaG[run2];
1757  for( run3 = 0; run3 < run1; run3++ ){
1758  G[diff_index[run2]] = G[diff_index[run2]] +
1759  A[run1][run3]*h[0]*k[run3][run2];
1760  }
1761  }
1762  if( rhs[0].AD_forward( number_+run1, G, k[run1] ) != SUCCESSFUL_RETURN ){
1764  return;
1765  }
1766  }
1767 
1768  // determine etaG:
1769  // ----------------------------------------------
1770  for( run1 = 0; run1 < dim; run1++ ){
1771  for( run2 = 0; run2 < m; run2++ ){
1772  etaG[run2] = etaG[run2] + b4[run1]*h[0]*k[run1][run2];
1773  }
1774  }
1775 }
1776 
1777 
1778 
1780 
1781  int run1, run2, run3;
1782 
1783  // determine k:
1784  // -----------------------------------------------
1785  for( run1 = 0; run1 < dim; run1++ ){
1786  for( run2 = 0; run2 < m; run2++ ){
1787  G2[diff_index[run2]] = etaG2[run2];
1788  G3[diff_index[run2]] = etaG3[run2];
1789  for( run3 = 0; run3 < run1; run3++ ){
1790  G2[diff_index[run2]] = G2[diff_index[run2]] +
1791  A[run1][run3]*h[0]*k[run3][run2];
1792  G3[diff_index[run2]] = G3[diff_index[run2]] +
1793  A[run1][run3]*h[0]*k2[run3][run2];
1794  }
1795  }
1796 
1797  if( rhs[0].AD_forward2( number_+run1, G2, G3, k[run1], k2[run1] )
1798  != SUCCESSFUL_RETURN ){
1800  return;
1801  }
1802  }
1803 
1804  // determine etaG2:
1805  // ----------------------------------------------
1806 
1807  for( run1 = 0; run1 < dim; run1++ ){
1808  for( run2 = 0; run2 < m; run2++ ){
1809  etaG2[run2] = etaG2[run2] + b4[run1]*h[0]*k[run1][run2];
1810  etaG3[run2] = etaG3[run2] + b4[run1]*h[0]*k2[run1][run2];
1811  }
1812  }
1813 }
1814 
1815 
1816 
1818 
1819  int run1, run2, run3;
1820  const int ndir = rhs->getNumberOfVariables() + 1 + m;
1821 
1822  for( run1 = 0; run1 < dim; run1++ ){
1823  for( run2 = 0; run2 < ndir; run2++ ){
1824  l[run1][run2] = 0.0;
1825  }
1826  }
1827  for( run1 = dim-1; run1 >= 0; run1--){
1828  for( run2 = 0; run2 < m; run2++ ){
1829  H[run2] = b4[run1]*h[0]*etaH[diff_index[run2]];
1830  for( run3 = run1+1; run3 < dim; run3++ ){
1831  H[run2] = H[run2] + A[run3][run1]*h[0]*l[run3][diff_index[run2]];
1832  }
1833  }
1834 
1835  if( rhs[0].AD_backward( number_+run1, H, l[run1] )!= SUCCESSFUL_RETURN ){
1837  return;
1838  }
1839  }
1840 
1841  // determine etaH:
1842  // ----------------------------------------------
1843  for( run1 = 0; run1 < dim; run1++ ){
1844  for( run2 = 0; run2 < ndir; run2++ ){
1845  etaH[run2] = etaH[run2] + l[run1][run2];
1846  }
1847  }
1848 }
1849 
1850 
1852 
1853  int run1, run2, run3;
1854  const int ndir = rhs->getNumberOfVariables() + 1 + m;
1855 
1856  for( run1 = 0; run1 < dim; run1++ ){
1857  for( run2 = 0; run2 < ndir; run2++ ){
1858  l [run1][run2] = 0.0;
1859  l2[run1][run2] = 0.0;
1860  }
1861  }
1862 
1863  for( run1 = dim-1; run1 >= 0; run1--){
1864  for( run2 = 0; run2 < m; run2++ ){
1865  H2[run2] = b4[run1]*h[0]*etaH2[diff_index[run2]];
1866  H3[run2] = b4[run1]*h[0]*etaH3[diff_index[run2]];
1867  for( run3 = run1+1; run3 < dim; run3++ ){
1868  H2[run2] = H2[run2] + A[run3][run1]*h[0]*l[run3][diff_index[run2]];
1869  H3[run2] = H3[run2] + A[run3][run1]*h[0]*l2[run3][diff_index[run2]];
1870  }
1871  }
1872  if( rhs[0].AD_backward2( number_+run1, H2, H3, l[run1], l2[run1] )
1873  != SUCCESSFUL_RETURN ){
1875  return;
1876  }
1877  }
1878 
1879  // determine etaH:
1880  // ----------------------------------------------
1881 
1882  for( run1 = 0; run1 < dim; run1++ ){
1883  for( run2 = 0; run2 < ndir; run2++ ){
1884  etaH2[run2] = etaH2[run2] + l [run1][run2];
1885  etaH3[run2] = etaH3[run2] + l2[run1][run2];
1886  }
1887  }
1888 }
1889 
1890 
1892 
1893  int run1, run2;
1894 
1895  if( soa != SOA_EVERYTHING_FROZEN ){
1896  for( run1 = 0; run1 < m; run1++ ){
1897  cout << "x[" << run1 << "] = " << eta4[run1] << " ";
1898  }
1899  cout << endl;
1900  }
1901  else{
1902 
1903  cout << endl;
1904  }
1905 
1906  // Forward Sensitivities:
1907  // ----------------------
1908 
1909  if( nFDirs > 0 && nBDirs2 == 0 && nFDirs2 == 0 ){
1910  cout << "RK: Forward Sensitivities:\n";
1911  for( run1 = 0; run1 < m; run1++ ){
1912  cout << scientific << etaG[run1] << " ";
1913  }
1914  cout << endl;
1915  }
1916 
1917 
1918  // 2nd Order Forward Sensitivities:
1919  // ---------------------------------
1920 
1921  if( nFDirs2 > 0 ){
1922 
1923  cout << "RK: First Order Forward Sensitivities:\n";
1924  for( run1 = 0; run1 < m; run1++ ){
1925  cout << scientific << etaG2[run1] << " ";
1926  }
1927  cout << endl;
1928 
1929  cout << "RK: Second Order Forward Sensitivities:\n";
1930  for( run1 = 0; run1 < m; run1++ ){
1931  cout << scientific << etaG3[run1] << " ";
1932  }
1933  cout << endl;
1934  }
1935 
1936  // Backward Sensitivities:
1937  // -----------------------
1938 
1939  if( nBDirs > 0 ){
1940 
1941  cout << "RK: Backward Sensitivities:\n";
1942 
1943  cout << "w.r.t. the states:\n" << scientific;
1944  for( run2 = 0; run2 < m; run2++ ){
1945  cout << etaH[diff_index[run2]] << " ";
1946  }
1947  cout << endl;
1948 
1949  if( mu > 0 ){
1950  cout << "w.r.t. the controls:\n" << scientific;
1951  for( run2 = 0; run2 < mu; run2++ ){
1952  cout << etaH[control_index[run2]] << " ";
1953  }
1954  cout << endl;
1955  }
1956  if( mp > 0 ){
1957  cout << "w.r.t. the parameters:\n" << scientific;;
1958  for( run2 = 0; run2 < mp; run2++ ){
1959  cout << etaH[parameter_index[run2]] << " ";
1960  }
1961  cout << endl;
1962  }
1963  if( mw > 0 ){
1964  cout << "w.r.t. the disturbances:\n" << scientific;;
1965  for( run2 = 0; run2 < mw; run2++ ){
1966  cout << etaH[disturbance_index[run2]] << " ";
1967  }
1968  cout << endl;
1969  }
1970  }
1971 
1972 
1973  // 2nd order Backward Sensitivities:
1974  // ---------------------------------
1975 
1976  if( nBDirs2 > 0 ){
1977 
1978  cout << "RK: First order Backward Sensitivities:\n";
1979 
1980  cout << "w.r.t. the states:\n" << scientific;;
1981  for( run2 = 0; run2 < m; run2++ ){
1982  cout << etaH2[diff_index[run2]] << " ";
1983  }
1984  cout << endl;
1985 
1986  if( mu > 0 ){
1987  cout << "w.r.t. the controls:\n" << scientific;;
1988  for( run2 = 0; run2 < mu; run2++ ){
1989  cout << etaH2[control_index[run2]] << " ";
1990  }
1991  cout << endl;
1992  }
1993  if( mp > 0 ){
1994  cout << "w.r.t. the parameters:\n" << scientific;;
1995  for( run2 = 0; run2 < mp; run2++ ){
1996  cout << etaH2[parameter_index[run2]] << " ";
1997  }
1998  cout << endl;
1999  }
2000  if( mw > 0 ){
2001  cout << "w.r.t. the disturbances:\n" << scientific;;
2002  for( run2 = 0; run2 < mw; run2++ ){
2003  cout << etaH2[disturbance_index[run2]] << " ";
2004  }
2005  cout << endl;
2006  }
2007 
2008  cout << "RK: Second order Backward Sensitivities:\n";
2009 
2010  cout << "w.r.t. the states:\n" << scientific;
2011  for( run2 = 0; run2 < m; run2++ ){
2012  cout << etaH3[diff_index[run2]] << " ";
2013  }
2014  cout << endl;
2015 
2016  if( mu > 0 ){
2017  cout << "w.r.t. the controls:\n" << scientific;
2018  for( run2 = 0; run2 < mu; run2++ ){
2019  cout << etaH3[control_index[run2]] << " ";
2020  }
2021  cout << "\n";
2022  }
2023 
2024  if( mp > 0 ){
2025  cout << "w.r.t. the parameters:\n" << scientific;
2026  for( run2 = 0; run2 < mp; run2++ ){
2027  cout << etaH3[parameter_index[run2]] << " ";
2028  }
2029  cout << "\n";
2030  }
2031 
2032  if( mw > 0 ){
2033  cout << "w.r.t. the disturbances:\n" << scientific;
2034  for( run2 = 0; run2 < mw; run2++ ){
2035  cout << etaH3[disturbance_index[run2]] << " ";
2036  }
2037  cout << "\n";
2038  }
2039  }
2040 }
2041 
2042 void IntegratorRK::interpolate( int jj, double *e1, double *d1, double *e2, VariablesGrid &poly ){
2043 
2044  int run1;
2045 
2046  for( run1 = 0; run1 < m; run1++ ){
2047 
2048  double cc = e1[run1];
2049  double bb = d1[run1];
2050  double aa = (e2[run1] - bb*h[0] - cc)/(h[0]*h[0]);
2051 
2052  double tt = timeInterval.getTime(jj) - t + h[0];
2053 
2054  poly( jj, run1 ) = aa*tt*tt + bb*tt + cc;
2055  }
2056 }
2057 
2058 
2060 
2061  return m;
2062 }
2063 
2064 
2066 
2067 
2068 // end of file.
returnValue setLast(LogName _name, int lastValue, double time=-INFTY)
int getStateEnumerationIndex(int index_)
virtual int getNumberOfSteps() const
double TOL
Definition: integrator.hpp:645
IntermediateState sqrt(const Expression &arg)
double tune
Definition: integrator.hpp:644
int getNPI() const
Definition: function.cpp:239
double getTime(uint pointIdx) const
int * int_parameter_index
Definition: integrator.hpp:659
void determineEtaHBackward(int number)
double getFirstTime() const
int maxNumberOfSteps
Definition: integrator.hpp:666
VariablesGrid dxStore
Definition: integrator.hpp:712
void constructAll(const IntegratorRK &arg)
virtual returnValue init(const DifferentialEquation &rhs_)
virtual returnValue getProtectedBackwardSensitivities(DVector &Dx_x0, DVector &Dx_p, DVector &Dx_u, DVector &Dx_w, int order) const
short int m
Definition: integrator.hpp:620
void initializeOptions()
Definition: integrator.cpp:587
BEGIN_NAMESPACE_ACADO const double EPS
virtual returnValue setProtectedForwardSeed(const DVector &xSeed, const DVector &pSeed, const DVector &uSeed, const DVector &wSeed, const int &order)
int getNDX() const
Definition: function.cpp:217
int * diff_index
Definition: integrator.hpp:653
void init(unsigned _dim=0)
Definition: vector.hpp:155
Provides a time grid consisting of vector-valued optimization variables at each grid point...
Allows to pass back messages to the calling function.
double hmin
Definition: integrator.hpp:642
AlgorithmicBase & operator=(const AlgorithmicBase &rhs)
int getNUI() const
Definition: function.cpp:227
IntermediateState pow(const Expression &arg1, const Expression &arg2)
int getNU() const
Definition: function.cpp:222
virtual double getStepSize() const
Allows to conveniently handle (one-dimensional) grids consisting of time points.
Definition: grid.hpp:58
RealClock functionEvaluation
Definition: integrator.hpp:695
virtual returnValue getProtectedX(DVector *xEnd) const
Grid timeInterval
Definition: integrator.hpp:648
#define CLOSE_NAMESPACE_ACADO
int * int_control_index
Definition: integrator.hpp:658
bool isEmpty() const
Definition: vector.hpp:176
int getNXA() const
Definition: function.cpp:212
virtual returnValue stop()
virtual int getDim() const
VariablesGrid ddxStore
Definition: integrator.hpp:713
Abstract base class for all kinds of algorithms for integrating differential equations (ODEs or DAEs)...
Definition: integrator.hpp:61
VariablesGrid xStore
Definition: integrator.hpp:711
uint getFloorIndex(double time) const
Definition: grid.cpp:593
int * alg_index
Definition: integrator.hpp:655
int getNW() const
Definition: function.cpp:245
StateOfAggregation soa
Definition: integrator.hpp:688
int nFcnEvaluations
Definition: integrator.hpp:696
BooleanType acadoIsNaN(double x)
virtual returnValue getProtectedForwardSensitivities(DMatrix *Dx, int order) const
void determineEtaGForward(int number)
int getNP() const
Definition: function.cpp:233
short int mu
Definition: integrator.hpp:624
virtual returnValue evaluate(const DVector &x0, const DVector &xa, const DVector &p, const DVector &u, const DVector &w, const Grid &t_)
virtual returnValue unfreeze()
void determineEtaGForward2(int number)
unsigned getDim() const
Definition: vector.hpp:172
int getDim() const
short int mw
Definition: integrator.hpp:628
double * h
Definition: integrator.hpp:640
double scale(VariableType variableType_, int index_) const
Definition: function.cpp:182
#define E
RealClock totalTime
Definition: integrator.hpp:694
returnValue init()
int getN() const
returnValue acadoPrintCopyrightNotice(const std::string &subpackage)
short int mui
Definition: integrator.hpp:625
int * control_index
Definition: integrator.hpp:656
Derived & setZero(Index size)
int * disturbance_index
Definition: integrator.hpp:660
int index(VariableType variableType_, int index_) const
Definition: function.cpp:176
virtual returnValue freezeAll()
short int mp
Definition: integrator.hpp:626
void interpolate(int jj, double *e1, double *d1, double *e2, VariablesGrid &poly)
PrintLevel
virtual returnValue freezeMesh()
virtual returnValue start()
Definition: real_clock.cpp:78
virtual IntegratorRK & operator=(const IntegratorRK &arg)
VariablesGrid iStore
Definition: integrator.hpp:714
virtual returnValue setBackwardSeed2(const DVector &seed)
#define ASSERT(x)
#define BT_TRUE
Definition: acado_types.hpp:47
short int mn
Definition: integrator.hpp:623
int * parameter_index
Definition: integrator.hpp:657
virtual int getNumberOfRejectedSteps() const
int * ddiff_index
Definition: integrator.hpp:654
virtual returnValue stop()
Definition: real_clock.cpp:107
double getLastTime() const
#define ACADOWARNING(retval)
#define BEGIN_NAMESPACE_ACADO
virtual returnValue step(int number)
DVector diff_scale
Definition: integrator.hpp:670
Abstract base class for all kinds of Runge-Kutta schemes for integrating ODEs.
short int ma
Definition: integrator.hpp:621
short int mpi
Definition: integrator.hpp:627
double hmax
Definition: integrator.hpp:643
virtual returnValue printRunTimeProfile() const
Definition: integrator.cpp:624
double hini
Definition: integrator.hpp:641
returnValue setForwardSeed2(const DVector &xSeed, const DVector &pSeed, const DVector &uSeed, const DVector &wSeed)
virtual returnValue evaluateSensitivities()
virtual returnValue setProtectedBackwardSeed(const DVector &seed, const int &order)
int getNumberOfVariables() const
Definition: function.cpp:264
#define ACADOERROR(retval)
virtual returnValue setDxInitialization(double *dx0)
virtual returnValue getTime(double &_elapsedTime)
Definition: clock.cpp:92
Allows to setup and evaluate differential equations (ODEs and DAEs) based on SymbolicExpressions.
DifferentialEquation * rhs
Definition: integrator.hpp:619
void determineEtaHBackward2(int number)


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