| 1 | #include <limits> |
|---|
| 2 | #include <exception> |
|---|
| 3 | |
|---|
| 4 | class ESCFunction |
|---|
| 5 | { |
|---|
| 6 | public: |
|---|
| 7 | virtual std::vector<float> init() = 0; |
|---|
| 8 | virtual float value(const std::vector<float> &state) const = 0; |
|---|
| 9 | }; |
|---|
| 10 | |
|---|
| 11 | class Gauss1D : public ESCFunction |
|---|
| 12 | { |
|---|
| 13 | private: |
|---|
| 14 | float a_, b_, c_, d_; |
|---|
| 15 | |
|---|
| 16 | public: |
|---|
| 17 | Gauss1D(float a=0, float b=1, float c=0, float d=1) : a_(a), b_(b), c_(c), d_(d) { } |
|---|
| 18 | |
|---|
| 19 | std::vector<float> init() |
|---|
| 20 | { |
|---|
| 21 | std::vector<float> state; |
|---|
| 22 | state.push_back(0); |
|---|
| 23 | return state; |
|---|
| 24 | } |
|---|
| 25 | |
|---|
| 26 | float value(const std::vector<float> &state) const |
|---|
| 27 | { |
|---|
| 28 | if (state.size() != 1) |
|---|
| 29 | throw std::runtime_error("invalid state size"); |
|---|
| 30 | |
|---|
| 31 | return a_ + b_*std::exp(-(state[0]-c_)*(state[0]-c_)/(2*d_*d_)); |
|---|
| 32 | } |
|---|
| 33 | }; |
|---|
| 34 | |
|---|
| 35 | class Gauss2D : public ESCFunction |
|---|
| 36 | { |
|---|
| 37 | private: |
|---|
| 38 | float a_, b_; |
|---|
| 39 | std::vector<float> c_, d_; |
|---|
| 40 | |
|---|
| 41 | public: |
|---|
| 42 | Gauss2D(float a, float b, std::vector<float> c, std::vector<float> d) |
|---|
| 43 | { |
|---|
| 44 | if (c.empty()) |
|---|
| 45 | { |
|---|
| 46 | c_.push_back(0); |
|---|
| 47 | c_.push_back(0); |
|---|
| 48 | } |
|---|
| 49 | else |
|---|
| 50 | c_ = c; |
|---|
| 51 | |
|---|
| 52 | if (d.empty()) |
|---|
| 53 | { |
|---|
| 54 | d_.push_back(1); |
|---|
| 55 | d_.push_back(1); |
|---|
| 56 | } |
|---|
| 57 | else |
|---|
| 58 | d_ = d; |
|---|
| 59 | } |
|---|
| 60 | |
|---|
| 61 | std::vector<float> init() |
|---|
| 62 | { |
|---|
| 63 | std::vector<float> state; |
|---|
| 64 | state.push_back(0); |
|---|
| 65 | state.push_back(0); |
|---|
| 66 | return state; |
|---|
| 67 | } |
|---|
| 68 | |
|---|
| 69 | float value(const std::vector<float> &state) const |
|---|
| 70 | { |
|---|
| 71 | if (state.size() != 1) |
|---|
| 72 | throw std::runtime_error("invalid state size"); |
|---|
| 73 | |
|---|
| 74 | double exponent = (state[0]-c_[0])*(state[0]-c_[0])/(2*d_[0]*d_[0]) + |
|---|
| 75 | (state[1]-c_[1])*(state[1]-c_[1])/(2*d_[1]*d_[1]); |
|---|
| 76 | |
|---|
| 77 | return a_ + b_*std::exp(-exponent); |
|---|
| 78 | } |
|---|
| 79 | }; |
|---|
| 80 | |
|---|
| 81 | |
|---|
| 82 | class ESCSystem |
|---|
| 83 | { |
|---|
| 84 | protected: |
|---|
| 85 | ESCFunction *function_; |
|---|
| 86 | std::vector<float> state_; |
|---|
| 87 | |
|---|
| 88 | public: |
|---|
| 89 | ESCSystem(ESCFunction *function) : function_(function) |
|---|
| 90 | { |
|---|
| 91 | if (!function) |
|---|
| 92 | throw std::runtime_error("no function specified"); |
|---|
| 93 | |
|---|
| 94 | reset(); |
|---|
| 95 | } |
|---|
| 96 | |
|---|
| 97 | void reset() |
|---|
| 98 | { |
|---|
| 99 | state_ = function_->init(); |
|---|
| 100 | } |
|---|
| 101 | |
|---|
| 102 | float step(const std::vector<float> &vel) |
|---|
| 103 | { |
|---|
| 104 | if (state_.size() != vel.size()) |
|---|
| 105 | throw std::runtime_error("invalid state size"); |
|---|
| 106 | |
|---|
| 107 | for (size_t ii=0; ii < state_.size() && ii < vel.size(); ++ii) |
|---|
| 108 | state_[ii] += vel[ii]; |
|---|
| 109 | |
|---|
| 110 | return function_->value(state_); |
|---|
| 111 | } |
|---|
| 112 | |
|---|
| 113 | float set(const std::vector<float> &pos) |
|---|
| 114 | { |
|---|
| 115 | if (state_.size() != pos.size()) |
|---|
| 116 | throw std::runtime_error("invalid state size"); |
|---|
| 117 | |
|---|
| 118 | state_ = pos; |
|---|
| 119 | return function_->value(state_); |
|---|
| 120 | } |
|---|
| 121 | |
|---|
| 122 | float value() const |
|---|
| 123 | { |
|---|
| 124 | return function_->value(state_); |
|---|
| 125 | } |
|---|
| 126 | |
|---|
| 127 | const std::vector<float> &state() |
|---|
| 128 | { |
|---|
| 129 | return state_; |
|---|
| 130 | } |
|---|
| 131 | }; |
|---|