Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages
LinearInterpolation.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // OpenMS -- Open-Source Mass Spectrometry
3 // --------------------------------------------------------------------------
4 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5 // ETH Zurich, and Freie Universitaet Berlin 2002-2017.
6 //
7 // This software is released under a three-clause BSD license:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of any author or any participating institution
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 // For a full list of authors, refer to the file AUTHORS.
17 // --------------------------------------------------------------------------
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // --------------------------------------------------------------------------
31 // $Maintainer: Timo Sachsenberg $
32 // $Authors: $
33 // --------------------------------------------------------------------------
34 
35 #ifndef OPENMS_MATH_MISC_LINEARINTERPOLATION_H
36 #define OPENMS_MATH_MISC_LINEARINTERPOLATION_H
37 
38 #include <OpenMS/CONCEPT/Types.h>
39 
40 #include <cmath> // for modf() (which is an overloaded function in C++)
41 #include <vector>
42 
43 namespace OpenMS
44 {
45 
46  namespace Math
47  {
48 
74  template <typename Key = double, typename Value = Key>
76  {
77 
78 public:
79 
81 
82  typedef Value value_type;
83 
84  typedef Key key_type;
85  typedef std::vector<value_type> container_type;
86 
87  typedef value_type ValueType;
88  typedef key_type KeyType;
89  typedef container_type ContainerType;
91 
92 public:
93 
101  LinearInterpolation(KeyType scale = 1., KeyType offset = 0.) :
102  scale_(scale),
103  offset_(offset),
104  inside_(),
105  outside_(),
106  data_()
107  {}
108 
111  scale_(arg.scale_),
112  offset_(arg.offset_),
113  inside_(arg.inside_),
114  outside_(arg.outside_),
115  data_(arg.data_)
116  {}
117 
120  {
121  if (&arg == this)
122  return *this;
123 
124  scale_ = arg.scale_;
125  offset_ = arg.offset_;
126  inside_ = arg.inside_;
127  outside_ = arg.outside_;
128  data_ = arg.data_;
129 
130  return *this;
131  }
132 
135 
136  // ----------------------------------------------------------------------
137 
139 
140 
142  ValueType value(KeyType arg_pos) const
143  {
144 
145  typedef typename container_type::difference_type DiffType;
146 
147  // apply the key transformation
148  KeyType left_key;
149  KeyType pos = key2index(arg_pos);
150  KeyType frac = std::modf(pos, &left_key);
151  DiffType const left = DiffType(left_key);
152 
153  // At left margin?
154  if (pos < 0)
155  {
156  if (left /* <= -1 */)
157  {
158  return 0;
159  }
160  else // left == 0
161  {
162  return data_[0] * (1 + frac);
163  }
164  }
165  else // pos >= 0
166  {
167  // At right margin?
168  DiffType const back = data_.size() - 1;
169  if (left >= back)
170  {
171  if (left != back)
172  {
173  return 0;
174  }
175  else
176  {
177  return data_[left] * (1 - frac);
178  }
179  }
180  else
181  {
182  // In between!
183  return data_[left + 1] * frac + data_[left] * (1 - frac);
184  }
185  }
186  }
187 
191  void addValue(KeyType arg_pos, ValueType arg_value)
192  {
193 
194  typedef typename container_type::difference_type DiffType;
195 
196  // apply the key transformation
197  KeyType left_key;
198  KeyType const pos = key2index(arg_pos);
199  KeyType const frac = std::modf(pos, &left_key);
200  DiffType const left = DiffType(left_key);
201 
202  // At left margin?
203  if (pos < 0)
204  {
205  if (left /* <= -1 */)
206  {
207  return;
208  }
209  else // left == 0
210  {
211  data_[0] += (1 + frac) * arg_value;
212  return;
213  }
214  }
215  else // pos >= 0
216  {
217  // At right margin?
218  DiffType const back = data_.size() - 1;
219  if (left >= back)
220  {
221  if (left != back)
222  {
223  return;
224  }
225  else // left == back
226  {
227  data_[left] += (1 - frac) * arg_value;
228  return;
229  }
230  }
231  else
232  {
233  // In between!
234  data_[left + 1] += frac * arg_value;
235  data_[left] += (1 - frac) * arg_value;
236  return;
237  }
238  }
239  }
240 
245  ValueType derivative(KeyType arg_pos) const
246  {
247 
248  // apply the key transformation
249  KeyType const pos = key2index(arg_pos);
250 
251  SignedSize const size_ = data_.size();
252  SignedSize const left = int(pos + 0.5); // rounds towards zero
253 
254  if (left < 0) // quite small
255  {
256  return 0;
257  }
258  else
259  {
260  if (left == 0) // at the border
261  {
262  if (pos >= -0.5) // that is: -0.5 <= pos < +0.5
263  {
264  return (data_[1] - data_[0]) * (pos + 0.5) + (data_[0]) * (0.5 - pos);
265  }
266  else // that is: -1.5 <= pos < -0.5
267  {
268  return (data_[0]) * (pos + 1.5);
269  }
270  }
271  }
272  // "else" case: to the right of the left margin
273 
274 
275  KeyType factor = KeyType(left) - pos + KeyType(0.5);
276 
277  if (left > size_) // quite large
278  {
279  return 0;
280  }
281  else
282  {
283  if (left < size_ - 1) // to the left of the right margin
284  {
285  // weighted average of derivatives for adjacent intervals
286  return (data_[left] - data_[left - 1]) * factor + (data_[left + 1] - data_[left]) * (1. - factor);
287  }
288  else // somewhat at the border
289  {
290  // at the border, first case
291  if (left == size_ - 1)
292  {
293  return (data_[left] - data_[left - 1]) * factor + (-data_[left]) * (1. - factor);
294  }
295  }
296  }
297  // else // that is: left == size_
298 
299  // We pull the last remaining case out of the "if" tree to avoid a
300  // compiler warning ...
301 
302  // at the border, second case
303  return (-data_[left - 1]) * factor;
304  }
305 
307 
308  // ----------------------------------------------------------------------
309 
311 
312 
314  ContainerType & getData()
315  {
316  return data_;
317  }
318 
320  ContainerType const & getData() const
321  {
322  return data_;
323  }
324 
330  template <typename SourceContainer>
331  void setData(SourceContainer const & data)
332  {
333  data_ = data;
334  }
335 
337  bool empty() const
338  {
339  return data_.empty();
340  }
341 
343 
344  // ----------------------------------------------------------------------
345 
347 
348 
350  KeyType key2index(KeyType pos) const
351  {
352  if (scale_)
353  {
354  pos -= offset_;
355  pos /= scale_;
356  return pos;
357  }
358  else
359  {
360  return 0;
361  }
362  }
363 
365  KeyType index2key(KeyType pos) const
366  {
367  pos *= scale_;
368  pos += offset_;
369  return pos;
370  }
371 
373  KeyType const & getScale() const
374  {
375  return scale_;
376  }
377 
383  void setScale(KeyType const & scale)
384  {
385  scale_ = scale;
386  }
387 
389  KeyType const & getOffset() const
390  {
391  return offset_;
392  }
393 
400  void setOffset(KeyType const & offset)
401  {
402  offset_ = offset;
403  }
404 
418  void setMapping(KeyType const & scale, KeyType const & inside, KeyType const & outside)
419  {
420  scale_ = scale;
421  inside_ = inside;
422  outside_ = outside;
423  offset_ = outside - scale * inside;
424  }
425 
432  void setMapping(KeyType const & inside_low, KeyType const & outside_low,
433  KeyType const & inside_high, KeyType const & outside_high)
434  {
435  if (inside_high != inside_low)
436  {
437  setMapping((outside_high - outside_low) / (inside_high - inside_low),
438  inside_low, outside_low);
439  }
440  else
441  {
442  setMapping(0, inside_low, outside_low);
443  }
444  return;
445  }
446 
448  KeyType const & getInsideReferencePoint() const
449  {
450  return inside_;
451  }
452 
454  KeyType const & getOutsideReferencePoint() const
455  {
456  return outside_;
457  }
458 
460  KeyType supportMin() const
461  {
462  return index2key(KeyType(empty() ? 0 : -1));
463  }
464 
466  KeyType supportMax() const
467  {
468  return index2key(KeyType(data_.size()));
469  }
470 
472 
473 protected:
474 
475  KeyType scale_;
476  KeyType offset_;
477  KeyType inside_;
478  KeyType outside_;
479 
480  ContainerType data_;
481 
482  };
483 
484  } // namespace Math
485 
486 } // namespace OpenMS
487 
488 #endif // OPENMS_MATH_MISC_LINEARINTERPOLATION_H
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:191
bool empty() const
Returns true if getData() is empty.
Definition: LinearInterpolation.h:337
KeyType index2key(KeyType pos) const
The transformation from "inside" to "outside" coordinates.
Definition: LinearInterpolation.h:365
std::vector< value_type > container_type
Definition: LinearInterpolation.h:85
void setScale(KeyType const &scale)
Accessor. "Scale" is the difference (in "outside" units) between consecutive entries in "Data"...
Definition: LinearInterpolation.h:383
KeyType const & getScale() const
Accessor. "Scale" is the difference (in "outside" units) between consecutive entries in "Data"...
Definition: LinearInterpolation.h:373
container_type ContainerType
Definition: LinearInterpolation.h:89
ptrdiff_t SignedSize
Signed Size type e.g. used as pointer difference.
Definition: Types.h:135
KeyType supportMax() const
Upper boundary of the support, in "outside" coordinates.
Definition: LinearInterpolation.h:466
~LinearInterpolation()
Destructor.
Definition: LinearInterpolation.h:134
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:47
KeyType const & getOffset() const
Accessor. "Offset" is the point (in "outside" units) which corresponds to "Data[0]".
Definition: LinearInterpolation.h:389
KeyType offset_
Definition: LinearInterpolation.h:476
KeyType outside_
Definition: LinearInterpolation.h:478
LinearInterpolation & operator=(LinearInterpolation const &arg)
Assignment operator.
Definition: LinearInterpolation.h:119
Provides access to linearly interpolated values (and derivatives) from discrete data points...
Definition: LinearInterpolation.h:75
ContainerType & getData()
Returns the internal random access container from which interpolated values are being sampled...
Definition: LinearInterpolation.h:314
ValueType value(KeyType arg_pos) const
Returns the interpolated value.
Definition: LinearInterpolation.h:142
ContainerType data_
Definition: LinearInterpolation.h:480
LinearInterpolation(LinearInterpolation const &arg)
Copy constructor.
Definition: LinearInterpolation.h:110
value_type ValueType
Definition: LinearInterpolation.h:87
KeyType const & getInsideReferencePoint() const
Accessor. See setMapping().
Definition: LinearInterpolation.h:448
Key key_type
Definition: LinearInterpolation.h:84
Value value_type
Definition: LinearInterpolation.h:82
ContainerType const & getData() const
Returns the internal random access container from which interpolated values are being sampled...
Definition: LinearInterpolation.h:320
KeyType inside_
Definition: LinearInterpolation.h:477
KeyType supportMin() const
Lower boundary of the support, in "outside" coordinates.
Definition: LinearInterpolation.h:460
LinearInterpolation(KeyType scale=1., KeyType offset=0.)
Constructors and destructor.
Definition: LinearInterpolation.h:101
key_type KeyType
Definition: LinearInterpolation.h:88
KeyType const & getOutsideReferencePoint() const
Accessor. See setMapping().
Definition: LinearInterpolation.h:454
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:432
ValueType derivative(KeyType arg_pos) const
Returns the interpolated derivative.
Definition: LinearInterpolation.h:245
void setData(SourceContainer const &data)
Assigns data to the internal random access container from which interpolated values are being sampled...
Definition: LinearInterpolation.h:331
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:418
KeyType scale_
Definition: LinearInterpolation.h:475
KeyType key2index(KeyType pos) const
The transformation from "outside" to "inside" coordinates.
Definition: LinearInterpolation.h:350
void setOffset(KeyType const &offset)
Accessor. "Offset" is the point (in "outside" units) which corresponds to "Data[0]".
Definition: LinearInterpolation.h:400

OpenMS / TOPP release 2.3.0 Documentation generated on Tue Jan 9 2018 18:22:01 using doxygen 1.8.13