OpenMS
Loading...
Searching...
No Matches
LinearInterpolation.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2// SPDX-License-Identifier: BSD-3-Clause
3//
4// --------------------------------------------------------------------------
5// $Maintainer: Timo Sachsenberg $
6// $Authors: $
7// --------------------------------------------------------------------------
8
9#pragma once
10
12
13#include <cmath> // for modf() (which is an overloaded function in C++)
14#include <vector>
15
16namespace OpenMS
17{
18
19 namespace Math
20 {
21
47 template <typename Key = double, typename Value = Key>
49 {
50
51public:
52
54
55 typedef Value value_type;
56
57 typedef Key key_type;
58 typedef std::vector<value_type> container_type;
59
64
65public:
66
74 LinearInterpolation(KeyType scale = 1., KeyType offset = 0.) :
75 scale_(scale),
76 offset_(offset),
77 inside_(),
78 outside_(),
79 data_()
80 {}
81
84 scale_(arg.scale_),
85 offset_(arg.offset_),
86 inside_(arg.inside_),
87 outside_(arg.outside_),
88 data_(arg.data_)
89 {}
90
93 {
94 if (&arg == this)
95 return *this;
96
97 scale_ = arg.scale_;
98 offset_ = arg.offset_;
99 inside_ = arg.inside_;
100 outside_ = arg.outside_;
101 data_ = arg.data_;
102
103 return *this;
104 }
105
108
109 // ----------------------------------------------------------------------
110
112
113
115 ValueType value(KeyType arg_pos) const
116 {
117
118 typedef typename container_type::difference_type DiffType;
119
120 // apply the key transformation
121 KeyType left_key;
122 KeyType pos = key2index(arg_pos);
123 KeyType frac = std::modf(pos, &left_key);
124 DiffType const left = DiffType(left_key);
125
126 // At left margin?
127 if (pos < 0)
128 {
129 if (left /* <= -1 */)
130 {
131 return 0;
132 }
133 else // left == 0
134 {
135 return data_[0] * (1 + frac);
136 }
137 }
138 else // pos >= 0
139 {
140 // At right margin?
141 DiffType const back = data_.size() - 1;
142 if (left >= back)
143 {
144 if (left != back)
145 {
146 return 0;
147 }
148 else
149 {
150 return data_[left] * (1 - frac);
151 }
152 }
153 else
154 {
155 // In between!
156 return data_[left + 1] * frac + data_[left] * (1 - frac);
157 }
158 }
159 }
160
164 void addValue(KeyType arg_pos, ValueType arg_value)
165 {
166
167 typedef typename container_type::difference_type DiffType;
168
169 // apply the key transformation
170 KeyType left_key;
171 KeyType const pos = key2index(arg_pos);
172 KeyType const frac = std::modf(pos, &left_key);
173 DiffType const left = DiffType(left_key);
174
175 // At left margin?
176 if (pos < 0)
177 {
178 if (left /* <= -1 */)
179 {
180 return;
181 }
182 else // left == 0
183 {
184 data_[0] += (1 + frac) * arg_value;
185 return;
186 }
187 }
188 else // pos >= 0
189 {
190 // At right margin?
191 DiffType const back = data_.size() - 1;
192 if (left >= back)
193 {
194 if (left != back)
195 {
196 return;
197 }
198 else // left == back
199 {
200 data_[left] += (1 - frac) * arg_value;
201 return;
202 }
203 }
204 else
205 {
206 // In between!
207 data_[left + 1] += frac * arg_value;
208 data_[left] += (1 - frac) * arg_value;
209 return;
210 }
211 }
212 }
213
219 {
220
221 // apply the key transformation
222 KeyType const pos = key2index(arg_pos);
223
224 SignedSize const size_ = data_.size();
225 SignedSize const left = int(pos + 0.5); // rounds towards zero
226
227 if (left < 0) // quite small
228 {
229 return 0;
230 }
231 else
232 {
233 if (left == 0) // at the border
234 {
235 if (pos >= -0.5) // that is: -0.5 <= pos < +0.5
236 {
237 return (data_[1] - data_[0]) * (pos + 0.5) + (data_[0]) * (0.5 - pos);
238 }
239 else // that is: -1.5 <= pos < -0.5
240 {
241 return (data_[0]) * (pos + 1.5);
242 }
243 }
244 }
245 // "else" case: to the right of the left margin
246
247
248 KeyType factor = KeyType(left) - pos + KeyType(0.5);
249
250 if (left > size_) // quite large
251 {
252 return 0;
253 }
254 else
255 {
256 if (left < size_ - 1) // to the left of the right margin
257 {
258 // weighted average of derivatives for adjacent intervals
259 return (data_[left] - data_[left - 1]) * factor + (data_[left + 1] - data_[left]) * (1. - factor);
260 }
261 else // somewhat at the border
262 {
263 // at the border, first case
264 if (left == size_ - 1)
265 {
266 return (data_[left] - data_[left - 1]) * factor + (-data_[left]) * (1. - factor);
267 }
268 }
269 }
270 // else // that is: left == size_
271
272 // We pull the last remaining case out of the "if" tree to avoid a
273 // compiler warning ...
274
275 // at the border, second case
276 return (-data_[left - 1]) * factor;
277 }
278
280
281 // ----------------------------------------------------------------------
282
284
285
288 {
289 return data_;
290 }
291
293 ContainerType const & getData() const
294 {
295 return data_;
296 }
297
303 template <typename SourceContainer>
304 void setData(SourceContainer const & data)
305 {
306 data_ = data;
307 }
308
310 bool empty() const
311 {
312 return data_.empty();
313 }
314
316
317 // ----------------------------------------------------------------------
318
320
321
324 {
325 if (scale_)
326 {
327 pos -= offset_;
328 pos /= scale_;
329 return pos;
330 }
331 else
332 {
333 return 0;
334 }
335 }
336
339 {
340 pos *= scale_;
341 pos += offset_;
342 return pos;
343 }
344
346 KeyType const & getScale() const
347 {
348 return scale_;
349 }
350
356 void setScale(KeyType const & scale)
357 {
358 scale_ = scale;
359 }
360
362 KeyType const & getOffset() const
363 {
364 return offset_;
365 }
366
373 void setOffset(KeyType const & offset)
374 {
375 offset_ = offset;
376 }
377
391 void setMapping(KeyType const & scale, KeyType const & inside, KeyType const & outside)
392 {
393 scale_ = scale;
394 inside_ = inside;
395 outside_ = outside;
396 offset_ = outside - scale * inside;
397 }
398
405 void setMapping(KeyType const & inside_low, KeyType const & outside_low,
406 KeyType const & inside_high, KeyType const & outside_high)
407 {
408 if (inside_high != inside_low)
409 {
410 setMapping((outside_high - outside_low) / (inside_high - inside_low),
411 inside_low, outside_low);
412 }
413 else
414 {
415 setMapping(0, inside_low, outside_low);
416 }
417 return;
418 }
419
422 {
423 return inside_;
424 }
425
428 {
429 return outside_;
430 }
431
434 {
435 return index2key(KeyType(empty() ? 0 : -1));
436 }
437
440 {
441 return index2key(KeyType(data_.size()));
442 }
443
445
446protected:
447
452
454
455 };
456
457 } // namespace Math
458
459} // namespace OpenMS
460
Provides access to linearly interpolated values (and derivatives) from discrete data points....
Definition LinearInterpolation.h:49
Value value_type
Definition LinearInterpolation.h:55
LinearInterpolation & operator=(LinearInterpolation const &arg)
Assignment operator.
Definition LinearInterpolation.h:92
KeyType key2index(KeyType pos) const
The transformation from "outside" to "inside" coordinates.
Definition LinearInterpolation.h:323
KeyType index2key(KeyType pos) const
The transformation from "inside" to "outside" coordinates.
Definition LinearInterpolation.h:338
KeyType supportMax() const
Upper boundary of the support, in "outside" coordinates.
Definition LinearInterpolation.h:439
Key key_type
Definition LinearInterpolation.h:57
ContainerType data_
Definition LinearInterpolation.h:453
ValueType derivative(KeyType arg_pos) const
Returns the interpolated derivative.
Definition LinearInterpolation.h:218
container_type ContainerType
Definition LinearInterpolation.h:62
void setData(SourceContainer const &data)
Assigns data to the internal random access container from which interpolated values are being sampled...
Definition LinearInterpolation.h:304
KeyType outside_
Definition LinearInterpolation.h:451
ContainerType & getData()
Returns the internal random access container from which interpolated values are being sampled.
Definition LinearInterpolation.h:287
bool empty() const
Returns true if getData() is empty.
Definition LinearInterpolation.h:310
KeyType const & getScale() const
Accessor. "Scale" is the difference (in "outside" units) between consecutive entries in "Data".
Definition LinearInterpolation.h:346
value_type ValueType
Definition LinearInterpolation.h:60
KeyType scale_
Definition LinearInterpolation.h:448
void setScale(KeyType const &scale)
Accessor. "Scale" is the difference (in "outside" units) between consecutive entries in "Data".
Definition LinearInterpolation.h:356
std::vector< value_type > container_type
Definition LinearInterpolation.h:58
LinearInterpolation(KeyType scale=1., KeyType offset=0.)
Constructors and destructor.
Definition LinearInterpolation.h:74
key_type KeyType
Definition LinearInterpolation.h:61
KeyType offset_
Definition LinearInterpolation.h:449
LinearInterpolation(LinearInterpolation const &arg)
Copy constructor.
Definition LinearInterpolation.h:83
void setMapping(KeyType const &inside_low, KeyType const &outside_low, KeyType const &inside_high, KeyType const &outside_high)
Specifies the mapping from "outside" to "inside" coordinates by the following data:
Definition LinearInterpolation.h:405
KeyType inside_
Definition LinearInterpolation.h:450
KeyType const & getInsideReferencePoint() const
Accessor. See setMapping().
Definition LinearInterpolation.h:421
KeyType const & getOutsideReferencePoint() const
Accessor. See setMapping().
Definition LinearInterpolation.h:427
KeyType const & getOffset() const
Accessor. "Offset" is the point (in "outside" units) which corresponds to "Data[0]".
Definition LinearInterpolation.h:362
void setOffset(KeyType const &offset)
Accessor. "Offset" is the point (in "outside" units) which corresponds to "Data[0]".
Definition LinearInterpolation.h:373
ContainerType const & getData() const
Returns the internal random access container from which interpolated values are being sampled.
Definition LinearInterpolation.h:293
void setMapping(KeyType const &scale, KeyType const &inside, KeyType const &outside)
Specifies the mapping from "outside" to "inside" coordinates by the following data:
Definition LinearInterpolation.h:391
~LinearInterpolation()=default
Destructor.
void addValue(KeyType arg_pos, ValueType arg_value)
Performs linear resampling. The arg_value is split up and added to the data points around arg_pos.
Definition LinearInterpolation.h:164
ValueType value(KeyType arg_pos) const
Returns the interpolated value.
Definition LinearInterpolation.h:115
KeyType supportMin() const
Lower boundary of the support, in "outside" coordinates.
Definition LinearInterpolation.h:433
ptrdiff_t SignedSize
Signed Size type e.g. used as pointer difference.
Definition Types.h:104
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19