discretization_runge_kutta.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Software License Agreement (BSD License) *
3  * Copyright (C) 2016 by Horatiu George Todoran <todorangrg@gmail.com> *
4  * *
5  * Redistribution and use in source and binary forms, with or without *
6  * modification, are permitted provided that the following conditions *
7  * are met: *
8  * *
9  * 1. Redistributions of source code must retain the above copyright *
10  * notice, this list of conditions and the following disclaimer. *
11  * 2. Redistributions in binary form must reproduce the above copyright *
12  * notice, this list of conditions and the following disclaimer in *
13  * the documentation and/or other materials provided with the *
14  * distribution. *
15  * 3. Neither the name of the copyright holder nor the names of its *
16  * contributors may be used to endorse or promote products derived *
17  * from this software without specific prior written permission. *
18  * *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
23  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY *
29  * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
30  * POSSIBILITY OF SUCH DAMAGE. *
31  ***************************************************************************/
32 
33 #ifndef DISCRETIZATION_RUNGE_KUTTA_HPP
34 #define DISCRETIZATION_RUNGE_KUTTA_HPP
35 
36 #include <float.h>
37 #include <memory>
38 #include <array>
39 
42 #include <boost/array.hpp>
43 
44 #include <algorithm>
45 
46 namespace tuw
47 {
48 namespace RungeKutta
49 {
50 namespace
51 {
52 template <std::size_t RKOrder>
53 inline constexpr const std::size_t aijIdx(const std::size_t& _i, const std::size_t& _j)
54 {
55  return 2 * RKOrder - 1 + _i * (_i + 1) / 2 + _j;
56 }
57 template <std::size_t RKOrder>
58 inline constexpr const std::size_t ciIdx(const std::size_t& _i)
59 {
60  return _i;
61 }
62 template <std::size_t RKOrder>
63 inline constexpr const std::size_t bjIdx(const std::size_t& _j)
64 {
65  return RKOrder - 1 + _j;
66 }
67 }
68 
80 template <std::size_t StateNmSize, std::size_t RKOrder, typename... RKCoeff>
81 void discretize(StateSim& _stateSim, const double& _arc)
82 {
83  static constexpr const std::array<double, sizeof...(RKCoeff)> coeff = {
84  { RKCoeff::val... }
85  }; // RungeKutta coefficients (specialized on order).
86  static std::array<StateArray<StateNmSize>, RKOrder> dX; // Array storing the partial continuous-time transition
87  // function evaluations of the system (specialized on state
88  // numeric variable size and order).
89  static StateArray<StateNmSize> x0, deltaXi, deltaX; // Helper variables (Specialized on state size).
90  static double _arc0, _dArc;
91  _arc0 = _stateSim.stateArc();
92  _dArc = _arc - _arc0;
93  if (_stateSim.stateNm().valueSize() != StateNmSize)
94  {
95  throw "Wrong specialization of RungeKutta::discretize called (system state value size != function state value "
96  "size) !";
97  }
98 
99  _stateSim.setStateCfNmStep(_arc0);
100  State& stateDot = _stateSim.stateNmDot();
101  const double& b0 = coeff[bjIdx<RKOrder>(0)];
102 
103  for (std::size_t si = 0; si < StateNmSize; ++si)
104  {
105  x0.value(si) = _stateSim.stateNm().value(si);
106  dX[0].value(si) = stateDot.value(si);
107  deltaX.value(si) = b0 * dX[0].value(si);
108  }
109 
110  for (std::size_t i = 0; i < RKOrder - 1; ++i)
111  {
112  deltaXi.valuesArray().fill(0);
113  for (std::size_t j = 0; j <= i; ++j)
114  {
115  const double& aij = coeff[aijIdx<RKOrder>(i, j)];
116  for (std::size_t si = 0; si < StateNmSize; ++si)
117  {
118  deltaXi.value(si) += aij * dX[j].value(si);
119  }
120  } // computes deltaX for step i
121 
122  for (std::size_t si = 0; si < StateNmSize; ++si)
123  {
124  _stateSim.stateNm().value(si) = x0.value(si) + _dArc * deltaXi.value(si);
125  }
126  _stateSim.setStateCfNmStep(
127  _arc0 + _dArc * coeff[ciIdx<RKOrder>(i)],
128  ParamFuncs::EvalArcGuarantee::AFTER_LAST); // set the closed form state at new evaluation arc
129  _stateSim.stateNmDot(); // compute continuous time state transition
130 
131  const double& bipp = coeff[bjIdx<RKOrder>(i + 1)];
132  for (std::size_t si = 0; si < StateNmSize; ++si)
133  {
134  dX[i + 1].value(si) = stateDot.value(si);
135  deltaX.value(si) += bipp * dX[i + 1].value(si);
136  } // store new transition and combine partial answers of the numerical state
137  } // computes all partial deltaXi of the numerical state for all steps
138  _stateSim.setStateCf(_arc0 + _dArc, ParamFuncs::EvalArcGuarantee::AFTER_LAST);
139  for (std::size_t si = 0; si < StateNmSize; ++si)
140  {
141  _stateSim.stateNm().value(si) = x0.value(si) + _dArc * deltaX.value(si);
142  } // set final state to the container
143 }
144 
146 template <>
147 inline void discretize<0, 0>(StateSim& _stateSim, const double& _arc)
148 {
149  static double _dArc;
150  _dArc = _arc - _stateSim.stateArc();
151  _stateSim.setStateCf(_arc, ParamFuncs::EvalArcGuarantee::AFTER_LAST);
152  State& stateDelta = _stateSim.stateNmDelta(_dArc);
153  for (std::size_t si = 0; si < _stateSim.stateNm().valueSize(); ++si)
154  {
155  _stateSim.stateNm().value(si) += stateDelta.value(si);
156  } // set final state to the container
157 }
158 }
159 }
160 
161 #endif // DISCRETIZATION_RUNGE_KUTTA_HPP
void discretize(StateSim &_stateSim, const double &_arc)
Templetized generic discretization function.
previous evaluation arc <= this evaluation arc
virtual State & stateNm()=0
Reference to the actual numerical-computed state.
virtual double & value(const std::size_t &_i)=0
Access state variable based on index _i.
void discretize< 0, 0 >(StateSim &_stateSim, const double &_arc)
Specialization for using a user-defined discretization function.
virtual void setStateCfNmStep(const double &_arc, const ParamFuncs::EvalArcGuarantee &_evalArcGuarantee=ParamFuncs::EvalArcGuarantee::AFTER_LAST)
Definition: state_sim.h:150
virtual double & value(const std::size_t &_i) override
Access state variable based on index _i.
Definition: state_array.hpp:98
virtual size_t valueSize() const =0
Size of the state variables.
Generic tree-like recursive structure that allows sub-structure access as well as ordered (array-like...
Definition: state.h:135
virtual State & stateNmDot()=0
Computes numerical continuous arc state transition (return) based on internal closed-form state (stat...
std::array< double, N > & valuesArray()
Reference to the state variables array.
virtual void setStateCf(const double &_arc, const ParamFuncs::EvalArcGuarantee &_evalArcGuarantee=ParamFuncs::EvalArcGuarantee::AFTER_LAST)=0
Sets closed-form state at arc _arc.
Interface for a state simulator structure that performs numerical integration of not-closed-form stat...
Definition: state_sim.h:58
virtual double stateArc() const =0
Value of the current arc parametrization of the state.


tuw_control
Author(s): George Todoran
autogenerated on Mon Jun 10 2019 15:27:21