codac 1.5.6
Loading...
Searching...
No Matches
codac2_SampledTraj.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include <map>
13#include "codac2_TrajBase.h"
16
17namespace codac2
18{
19 template<typename T>
20 class SampledTraj : public TrajBase<T>, public std::map<double,T>
21 {
22 public:
23
24 SampledTraj()
25 : TrajBase<T>(), std::map<double,T>()
26 { }
27
28 SampledTraj(const std::list<double>& l_t, const std::list<T>& l_x)
29 : SampledTraj()
30 {
31 assert_release(l_t.size() == l_x.size());
32 auto it_t = l_t.begin(); auto it_x = l_x.begin();
33 while(it_t != l_t.end())
34 {
35 this->set(*it_t,*it_x);
36 it_t++; it_x++;
37 }
38 }
39
40 SampledTraj(const std::map<double,T>& m)
41 : TrajBase<T>(), std::map<double,T>(m)
42 { }
43
44 // size is not the std::map<double,T>::size() !
45 virtual Index size() const
46 {
47 if constexpr(std::is_same_v<typename ValueType<T>::Type,ScalarType>)
48 return 1;
49
50 else
51 {
52 if(this->empty())
53 return 0;
54 else
55 return this->begin()->second.size();
56 }
57 }
58
59 size_t nb_samples() const
60 {
61 return std::map<double,T>::size();
62 }
63
64 virtual bool is_empty() const
65 {
66 return std::map<double,T>::empty();
67 }
68
69 virtual Interval tdomain() const
70 {
71 if(this->empty())
72 return Interval::empty();
73 else
74 return { this->begin()->first, this->rbegin()->first };
75 }
76
77 virtual void truncate_tdomain(const Interval& new_tdomain)
78 {
79 assert_release(this->tdomain().is_superset(new_tdomain));
80
81 // Interpolation on the limits of the new tdomain
82 T y_lb = (*this)(new_tdomain.lb());
83 T y_ub = (*this)(new_tdomain.ub());
84
85 auto it = this->begin();
86 while(it != this->end())
87 {
88 if(!new_tdomain.contains(it->first))
89 it = this->erase(it);
90 else
91 ++it;
92 }
93
94 this->set(new_tdomain.lb(), y_lb); // clean truncation
95 this->set(new_tdomain.ub(), y_ub);
96 }
97
98 virtual typename Wrapper<T>::Domain codomain() const
99 {
100 typename Wrapper<T>::Domain hull(this->begin()->second);
101 for(const auto& [t,v] : *this)
102 hull |= v;
103 return hull;
104 }
105
106 virtual T operator()(double t) const
107 {
108 if(!this->tdomain().contains(t))
109 return this->nan_value();
110
111 auto it_lower = this->lower_bound(t);
112 if(it_lower->first == t)
113 return it_lower->second;
114
115 auto it_upper = it_lower;
116 it_lower--;
117
118 // Linear interpolation
119 return it_lower->second +
120 (t - it_lower->first) * (it_upper->second - it_lower->second) /
121 (it_upper->first - it_lower->first);
122 }
123
124 virtual typename Wrapper<T>::Domain operator()(const Interval& t) const
125 {
126 // We obtain the output dimension by an evalution...
127 typename Wrapper<T>::Domain hull(this->begin()->second);
128
129 if(!this->tdomain().is_superset(t))
130 return hull.init(Interval(-oo,oo));
131
132 else
133 {
134 hull = (*this)(t.lb());
135 for(auto it = this->lower_bound(t.lb()) ; it != this->upper_bound(t.ub()) ; it++)
136 hull |= it->second;
137 hull |= (*this)(t.ub());
138 return hull;
139 }
140 }
141
142 void set(double t, const T& x)
143 {
144 assert(this->empty() || size_of(x) == this->size());
145 std::map<double,T>::operator[](t) = x;
146 }
147
148 virtual SampledTraj<T> sampled(double dt) const
149 {
150 return sampled(dt, true);
151 }
152
153 SampledTraj<T> sampled(double dt, bool keep_original_values) const
154 {
155 assert(dt > 0.);
156 assert(!is_empty());
157
158 auto straj = TrajBase<T>::sampled(dt);
159
160 if(keep_original_values)
161 {
162 // Appending values from the initial map:
163 for(const auto& [ti,xi] : *this)
164 straj.set(ti, xi);
165 }
166
167 return straj;
168 }
169
170 template<typename Q>
171 SampledTraj<T> sampled_as(const SampledTraj<Q>& x) const
172 {
173 return TrajBase<T>::sampled_as(x);
174 }
175
176 template<typename Q>
177 SampledTraj<T> sampled_as(const SampledTraj<Q>& x, bool keep_original_values) const
178 {
179 SampledTraj<T> straj = TrajBase<T>::sampled_as(x);
180 if(keep_original_values)
181 for(const auto& [ti,xi] : *this)
182 straj.set(ti, xi);
183 return straj;
184 }
185
186 SampledTraj<T>& shift_tdomain(double shift)
187 {
188 std::map<double,T> save = *this;
189 this->clear();
190 for(const auto& [ti,xi] : save)
191 this->std::map<double,T>::operator[](ti+shift) = xi;
192 return *this;
193 }
194
195 SampledTraj<T>& stretch_tdomain(const Interval& tdomain)
196 {
197 Interval a = this->tdomain(), b = tdomain;
198 std::map<double,T> save = *this;
199 this->clear();
200 for(const auto& [ti,xi] : save)
201 this->std::map<double,T>::operator[]([&]() {
202 if(ti == a.ub())
203 return b.ub(); // due to floating point possible error
204 else
205 return ((ti-a.lb())*b.diam()/a.diam())+b.lb();
206 }()
207 ) = xi;
208 assert(this->tdomain() == tdomain);
209 return *this;
210 }
211
212 template<typename T_=T>
213 requires std::is_same_v<T_,Vector>
214 SampledTraj<double> operator[](Index i) const
215 {
216 assert_release(i >= 0 && i < size());
217 std::map<double,double> m;
218 for(const auto& [t,y] : *this)
219 {
220 assert(i < y.size());
221 m[t] = y[i];
222 }
223
224 return { m };
225 }
226
227 template<typename T_=T>
228 requires std::is_same_v<T_,Vector>
229 SampledTraj<Vector> subvector(Index i, Index j) const
230 {
231 assert_release(i >= 0 && i <= j && j < size());
232 std::map<double,Vector> m;
233 for(const auto& [t,y] : *this)
234 {
235 assert(j < y.size());
236 m[t] = y.subvector(i,j);
237 }
238
239 return { m };
240 }
241 };
242
243 template<typename T>
244 inline std::ostream& operator<<(std::ostream& os, const SampledTraj<T>& x)
245 {
246 os << "SampledTraj. " << x.tdomain() << "↦" << x.codomain() << ", " << x.nb_samples() << " pts";
247 return os;
248 }
249
250 inline SampledTraj<double> continuous_traj(const SampledTraj<double>& x)
251 {
252 SampledTraj<double> x_continuous;
253 const Interval periodicity = x.codomain();
254
255 double prev_xi = 0., value_mod = 0.;
256
257 for(const auto& [ti,xi] : x)
258 {
259 if(!x_continuous.empty())
260 {
261 if(prev_xi - xi > periodicity.diam()*0.9)
262 value_mod += periodicity.diam();
263 else if(prev_xi - xi < -periodicity.diam()*0.9)
264 value_mod -= periodicity.diam();
265 }
266
267 prev_xi = xi;
268 x_continuous.set(ti, xi+value_mod);
269 }
270
271 return x_continuous;
272 }
273}
Interval class, for representing closed and connected subsets of .
Definition codac2_Interval.h:62
static Interval empty()
Provides an empty interval.
Definition codac2_Interval_impl.h:535
std::ostream & operator<<(std::ostream &os, const BoolInterval &x)
Streams out a BoolInterval.
Definition codac2_BoolInterval.h:45