OpenMS
Loading...
Searching...
No Matches
BilinearInterpolation.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#include <cmath>
13
14namespace OpenMS
15{
16
17 namespace Math
18 {
19
46 template <typename Key = double, typename Value = Key>
48 {
49
50public:
51
53
54 typedef Value value_type;
55
56 typedef Key key_type;
58
63
64public:
65
69
72 scale_0_(1),
73 offset_0_(0),
74 scale_1_(1),
75 offset_1_(0),
76 inside_0_(0),
77 outside_0_(0),
78 inside_1_(0),
79 outside_1_(0),
80 data_()
81 {}
82
95
98 {
99 if (&arg == this)
100 return *this;
101
102 scale_0_ = arg.scale_0_;
103 offset_0_ = arg.offset_0_;
104 scale_1_ = arg.scale_1_;
105 offset_1_ = arg.offset_1_;
106 inside_0_ = arg.inside_0_;
108 inside_1_ = arg.inside_1_;
110 data_ = arg.data_;
111 return *this;
112 }
113
117
119
120 // ----------------------------------------------------------------------
121
123
124
126 ValueType value(KeyType arg_pos_0, KeyType arg_pos_1) const
127 {
128 // apply the key transformations
129 KeyType const pos_0 = key2index_0(arg_pos_0);
130 KeyType const pos_1 = key2index_1(arg_pos_1);
131
132 // ???? should use modf() here!
133
134 SignedSize const size_0 = data_.rows();
135 SignedSize const lower_0 = SignedSize(pos_0); // this rounds towards zero
136 SignedSize const size_1 = data_.cols();
137 SignedSize const lower_1 = SignedSize(pos_1); // this rounds towards zero
138
139 // small pos_0
140 if (pos_0 <= 0)
141 {
142 if (lower_0 != 0)
143 {
144 return 0;
145 }
146 else // that is: -1 < pos_0 <= 0
147 { // small pos_1
148 if (pos_1 <= 0)
149 {
150 if (lower_1 != 0)
151 {
152 return 0;
153 }
154 else // that is: -1 < pos_1 <= 0
155 {
156 return data_(0, 0) * (1. + pos_0) * (1. + pos_1);
157 }
158 }
159
160 // big pos_1
161 if (lower_1 >= size_1 - 1)
162 {
163 if (lower_1 != size_1 - 1)
164 {
165 return 0;
166 }
167 else
168 {
169 return data_(0, lower_1) * (1. + pos_0) * (size_1 - pos_1);
170 }
171 }
172
173 // medium pos_1
174 KeyType const factor_1 = pos_1 - KeyType(lower_1);
175 KeyType const factor_1_complement = KeyType(1.) - factor_1;
176 return (
177 data_(0, lower_1 + 1) * factor_1 +
178 data_(0, lower_1) * factor_1_complement
179 ) * (1. + pos_0);
180 }
181 }
182
183 // big pos_0
184 if (lower_0 >= size_0 - 1)
185 {
186 if (lower_0 != size_0 - 1)
187 {
188 return 0;
189 }
190 else // that is: size_0 - 1 <= pos_0 < size_0
191 { // small pos_1
192 if (pos_1 <= 0)
193 {
194 if (lower_1 != 0)
195 {
196 return 0;
197 }
198 else // that is: -1 < pos_1 <= 0
199 {
200 return data_(lower_0, 0) * (size_0 - pos_0) * (1. + pos_1);
201 }
202 }
203
204 // big pos_1
205 if (lower_1 >= size_1 - 1)
206 {
207 if (lower_1 != size_1 - 1)
208 {
209 return 0;
210 }
211 else
212 {
213 return data_(lower_0, lower_1) * (size_0 - pos_0) * (size_1 - pos_1);
214 }
215 }
216
217 // medium pos_1
218 KeyType const factor_1 = pos_1 - KeyType(lower_1);
219 KeyType const factor_1_complement = KeyType(1.) - factor_1;
220 return (
221 data_(lower_0, lower_1 + 1) * factor_1 +
222 data_(lower_0, lower_1) * factor_1_complement
223 )
224 * (size_0 - pos_0);
225 }
226 }
227
228 // medium pos_0
229 {
230 KeyType const factor_0 = pos_0 - KeyType(lower_0);
231 KeyType const factor_0_complement = KeyType(1.) - factor_0;
232
233 // small pos_1
234 if (pos_1 <= 0)
235 {
236 if (lower_1 != 0)
237 {
238 return 0;
239 }
240 else // that is: -1 < pos_1 <= 0
241 {
242 return (
243 data_(lower_0 + 1, 0) * factor_0
244 +
245 data_(lower_0, 0) * factor_0_complement
246 )
247 * (1. + pos_1);
248 }
249 }
250
251 // big pos_1
252 if (lower_1 >= size_1 - 1)
253 {
254 if (lower_1 != size_1 - 1)
255 {
256 return 0;
257 }
258 else
259 {
260 return (
261 data_(lower_0 + 1, lower_1) * factor_0
262 +
263 data_(lower_0, lower_1) * factor_0_complement
264 )
265 * (size_1 - pos_1);
266 }
267 }
268 KeyType const factor_1 = pos_1 - KeyType(lower_1);
269 KeyType const factor_1_complement = KeyType(1.) - factor_1;
270
271 // medium pos_0 and medium pos_1 --> "within" the matrix
272 return (
273 data_(lower_0 + 1, lower_1 + 1) * factor_0
274 +
275 data_(lower_0, lower_1 + 1) * factor_0_complement
276 )
277 * factor_1
278 +
279 (
280 data_(lower_0 + 1, lower_1) * factor_0
281 +
282 data_(lower_0, lower_1) * factor_0_complement
283 )
284 * factor_1_complement;
285 }
286 }
287
291 void addValue(KeyType arg_pos_0, KeyType arg_pos_1, ValueType arg_value)
292 {
293
294 typedef typename std::ptrdiff_t DiffType;
295
296 // apply key transformation _0
297 KeyType const pos_0 = key2index_0(arg_pos_0);
298 KeyType lower_0_key;
299 KeyType const frac_0 = std::modf(pos_0, &lower_0_key);
300 DiffType const lower_0 = DiffType(lower_0_key);
301
302 // Small pos_0 ?
303 if (pos_0 < 0)
304 {
305 if (lower_0)
306 {
307 return;
308 }
309 else // lower_0 == 0
310 { // apply key transformation _1
311 KeyType const pos_1 = key2index_1(arg_pos_1);
312 KeyType lower_1_key;
313 KeyType const frac_1 = std::modf(pos_1, &lower_1_key);
314 DiffType const lower_1 = DiffType(lower_1_key);
315
316 // Small pos_1 ?
317 if (pos_1 < 0)
318 {
319 if (lower_1)
320 {
321 return;
322 }
323 else // lower_1 == 0
324 {
325 data_(0, 0) += arg_value * (1 + frac_0) * (1 + frac_1);
326 return;
327 }
328 }
329 else // pos_1 >= 0
330 {
331 DiffType const back_1 = data_.cols() - 1;
332 // big pos_1
333 if (lower_1 >= back_1)
334 {
335 if (lower_1 != back_1)
336 {
337 return;
338 }
339 else // lower_1 == back_1
340 {
341 data_(0, lower_1) += arg_value * (1 + frac_0) * (1 - frac_1);
342 return;
343 }
344 }
345 else
346 {
347 // medium pos_1
348 KeyType const tmp_prod = KeyType(arg_value * (1. + frac_0));
349 data_(0, lower_1 + 1) += tmp_prod * frac_1;
350 data_(0, lower_1) += tmp_prod * (1. - frac_1);
351 return;
352 }
353 }
354 }
355 }
356 else // pos_0 >= 0
357 {
358 DiffType const back_0 = data_.rows() - 1;
359 if (lower_0 >= back_0)
360 {
361 if (lower_0 != back_0)
362 {
363 return;
364 }
365 else // lower_0 == back_0
366 {
367
368 KeyType const tmp_prod = KeyType(arg_value * (1. - frac_0));
369
370 // apply key transformation _1
371 KeyType const pos_1 = key2index_1(arg_pos_1);
372 KeyType lower_1_key;
373 KeyType const frac_1 = std::modf(pos_1, &lower_1_key);
374 DiffType const lower_1 = DiffType(lower_1_key);
375
376 // Small pos_1 ?
377 if (pos_1 < 0)
378 {
379 if (lower_1)
380 {
381 return;
382 }
383 else // lower_1 == 0
384 {
385 data_(lower_0, 0) += tmp_prod * (1 + frac_1);
386 return;
387 }
388 }
389 else // pos_1 >= 0
390 {
391 DiffType const back_1 = data_.cols() - 1;
392 // big pos_1
393 if (lower_1 >= back_1)
394 {
395 if (lower_1 != back_1)
396 {
397 return;
398 }
399 else // lower_1 == back_1
400 {
401 data_(lower_0, lower_1) += tmp_prod * (1 - frac_1);
402 return;
403 }
404 }
405 else
406 {
407 // medium pos_1
408 data_(lower_0, lower_1 + 1) += tmp_prod * frac_1;
409 data_(lower_0, lower_1) += tmp_prod * (1 - frac_1);
410 return;
411 }
412 }
413 }
414 }
415 else // lower_0 < back_0
416 {
417
418 // Medium pos_0 !
419
420 // apply key transformation _1
421 KeyType const pos_1 = key2index_1(arg_pos_1);
422 KeyType lower_1_key;
423 KeyType const frac_1 = std::modf(pos_1, &lower_1_key);
424 DiffType const lower_1 = DiffType(lower_1_key);
425
426 // Small pos_1 ?
427 if (pos_1 < 0)
428 {
429 if (lower_1)
430 {
431 return;
432 }
433 else // lower_1 == 0
434 {
435 KeyType const tmp_prod = KeyType(arg_value * (1 + frac_1));
436 data_(lower_0 + 1, 0) += tmp_prod * frac_0;
437 data_(lower_0, 0) += tmp_prod * (1 - frac_0);
438 return;
439 }
440 }
441 else // pos_1 >= 0
442 {
443 DiffType const back_1 = data_.cols() - 1;
444 // big pos_1
445 if (lower_1 >= back_1)
446 {
447 if (lower_1 != back_1)
448 {
449 return;
450 }
451 else // lower_1 == back_1
452 {
453 KeyType const tmp_prod = KeyType(arg_value * (1 - frac_1));
454 data_(lower_0 + 1, lower_1) += tmp_prod * frac_0;
455 data_(lower_0, lower_1) += tmp_prod * (1 - frac_0);
456 return;
457 }
458 }
459 else
460 {
461 // Medium pos_1 !
462
463 // medium pos_0 and medium pos_1 --> "within" the matrix
464 KeyType tmp_prod = KeyType(arg_value * frac_0);
465 data_(lower_0 + 1, lower_1 + 1) += tmp_prod * frac_1;
466 data_(lower_0 + 1, lower_1) += tmp_prod * (1 - frac_1);
467 tmp_prod = KeyType(arg_value * (1 - frac_0));
468 data_(lower_0, lower_1 + 1) += tmp_prod * frac_1;
469 data_(lower_0, lower_1) += tmp_prod * (1 - frac_1);
470 return;
471 }
472 }
473 }
474 }
475 }
476
478
479 // ----------------------------------------------------------------------
480
482
483
486 {
487 return data_;
488 }
489
491 ContainerType const & getData() const
492 {
493 return data_;
494 }
495
501 template <typename SourceContainer>
502 void setData(SourceContainer const & data)
503 {
504 data_ = data;
505 }
506
508 bool empty() const
509 {
510 return data_.empty();
511 }
512
514
515 // ----------------------------------------------------------------------
516
518
519
522 {
523 if (scale_0_)
524 {
525 pos -= offset_0_;
526 pos /= scale_0_;
527 return pos;
528 }
529 else
530 {
531 return 0;
532 }
533 }
534
537 {
538 pos *= scale_0_;
539 pos += offset_0_;
540 return pos;
541 }
542
545 {
546 if (scale_1_)
547 {
548 pos -= offset_1_;
549 pos /= scale_1_;
550 return pos;
551 }
552 else
553 {
554 return 0;
555 }
556 }
557
560 {
561 pos *= scale_1_;
562 pos += offset_1_;
563 return pos;
564 }
565
567 KeyType const & getScale_0() const
568 {
569 return scale_0_;
570 }
571
573 KeyType const & getScale_1() const
574 {
575 return scale_1_;
576 }
577
583 void setScale_0(KeyType const & scale)
584 {
585 scale_0_ = scale;
586 }
587
593 void setScale_1(KeyType const & scale)
594 {
595 scale_1_ = scale;
596 }
597
599 KeyType const & getOffset_0() const
600 {
601 return offset_0_;
602 }
603
605 KeyType const & getOffset_1() const
606 {
607 return offset_1_;
608 }
609
616 void setOffset_0(KeyType const & offset)
617 {
618 offset_0_ = offset;
619 }
620
627 void setOffset_1(KeyType const & offset)
628 {
629 offset_1_ = offset;
630 }
631
645 void setMapping_0(KeyType const & scale, KeyType const & inside_low, KeyType const & outside_low)
646 {
647 scale_0_ = scale;
648 inside_0_ = inside_low;
649 outside_0_ = outside_low;
650 offset_0_ = outside_low - scale * inside_low;
651 return;
652 }
653
660 void setMapping_0(KeyType const & inside_low, KeyType const & outside_low,
661 KeyType const & inside_high, KeyType const & outside_high)
662 {
663 if (inside_high != inside_low)
664 {
665 setMapping_0((outside_high - outside_low) / (inside_high - inside_low),
666 inside_low, outside_low);
667 }
668 else
669 {
670 setMapping_0(0, inside_low, outside_low);
671 }
672 return;
673 }
674
688 void setMapping_1(KeyType const & scale, KeyType const & inside_low, KeyType const & outside_low)
689 {
690 scale_1_ = scale;
691 inside_1_ = inside_low;
692 outside_1_ = outside_low;
693 offset_1_ = outside_low - scale * inside_low;
694 return;
695 }
696
703 void setMapping_1(KeyType const & inside_low, KeyType const & outside_low,
704 KeyType const & inside_high, KeyType const & outside_high)
705 {
706 if (inside_high != inside_low)
707 {
708 setMapping_1((outside_high - outside_low) / (inside_high - inside_low),
709 inside_low, outside_low);
710 }
711 else
712 {
713 setMapping_1(0, inside_low, outside_low);
714 }
715 return;
716 }
717
720 {
721 return inside_0_;
722 }
723
726 {
727 return inside_1_;
728 }
729
732 {
733 return outside_0_;
734 }
735
738 {
739 return outside_1_;
740 }
741
744 {
745 return index2key_0(empty() ? KeyType(0.) : KeyType(-1.));
746 }
747
750 {
751 return index2key_1(empty() ? KeyType(0.) : KeyType(-1.));
752 }
753
756 {
757 return index2key_0(KeyType(data_.rows()));
758 }
759
762 {
763 return index2key_1(KeyType(data_.cols()));
764 }
765
767
768protected:
769
782 };
783
784 } // namespace Math
785
786} // namespace OpenMS
787
Provides access to bilinearly interpolated values (and derivatives) from discrete data points....
Definition BilinearInterpolation.h:48
Value value_type
Definition BilinearInterpolation.h:54
KeyType supportMin_1() const
Lower boundary of the support, in "outside" coordinates.
Definition BilinearInterpolation.h:749
ValueType value(KeyType arg_pos_0, KeyType arg_pos_1) const
Returns the interpolated value ("backward resampling")
Definition BilinearInterpolation.h:126
KeyType const & getInsideReferencePoint_1() const
Accessor. See setMapping().
Definition BilinearInterpolation.h:725
KeyType const & getOffset_1() const
Accessor. "Offset" is the point (in "outside" units) which corresponds to "Data(0,...
Definition BilinearInterpolation.h:605
Key key_type
Definition BilinearInterpolation.h:56
Matrix< value_type > container_type
Definition BilinearInterpolation.h:57
ContainerType data_
Definition BilinearInterpolation.h:780
container_type ContainerType
Definition BilinearInterpolation.h:61
void setData(SourceContainer const &data)
Assigns data to the internal random access container storing the data.
Definition BilinearInterpolation.h:502
KeyType outside_0_
Definition BilinearInterpolation.h:777
void setMapping_1(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 BilinearInterpolation.h:703
KeyType supportMax_1() const
Upper boundary of the support, in "outside" coordinates.
Definition BilinearInterpolation.h:761
KeyType inside_1_
Definition BilinearInterpolation.h:778
BilinearInterpolation(BilinearInterpolation const &arg)
Copy constructor.
Definition BilinearInterpolation.h:84
ContainerType & getData()
Returns the internal random access container storing the data.
Definition BilinearInterpolation.h:485
void setMapping_1(KeyType const &scale, KeyType const &inside_low, KeyType const &outside_low)
Specifies the mapping from "outside" to "inside" coordinates by the following data:
Definition BilinearInterpolation.h:688
bool empty() const
Returns true if getData() is empty.
Definition BilinearInterpolation.h:508
KeyType supportMax_0() const
Upper boundary of the support, in "outside" coordinates.
Definition BilinearInterpolation.h:755
KeyType const & getScale_1() const
Accessor. "Scale" is the difference (in "outside" units) between consecutive entries in "Data".
Definition BilinearInterpolation.h:573
KeyType const & getInsideReferencePoint_0() const
Accessor. See setMapping().
Definition BilinearInterpolation.h:719
void setOffset_1(KeyType const &offset)
Accessor. "Offset" is the point (in "outside" units) which corresponds to "Data(0,...
Definition BilinearInterpolation.h:627
void setMapping_0(KeyType const &scale, KeyType const &inside_low, KeyType const &outside_low)
Specifies the mapping from "outside" to "inside" coordinates by the following data:
Definition BilinearInterpolation.h:645
value_type ValueType
Definition BilinearInterpolation.h:59
KeyType scale_1_
Definition BilinearInterpolation.h:774
BilinearInterpolation()
Constructors and destructor.
Definition BilinearInterpolation.h:71
KeyType index2key_0(KeyType pos) const
The transformation from "inside" to "outside" coordinates.
Definition BilinearInterpolation.h:536
KeyType offset_0_
Definition BilinearInterpolation.h:773
KeyType scale_0_
Data members.
Definition BilinearInterpolation.h:772
KeyType inside_0_
Definition BilinearInterpolation.h:776
BilinearInterpolation & operator=(BilinearInterpolation const &arg)
Assignment operator.
Definition BilinearInterpolation.h:97
void setMapping_0(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 BilinearInterpolation.h:660
void addValue(KeyType arg_pos_0, KeyType arg_pos_1, ValueType arg_value)
Performs bilinear resampling. The arg_value is split up and added to the data points around arg_pos....
Definition BilinearInterpolation.h:291
KeyType const & getScale_0() const
Accessor. "Scale" is the difference (in "outside" units) between consecutive entries in "Data".
Definition BilinearInterpolation.h:567
key_type KeyType
Definition BilinearInterpolation.h:60
KeyType offset_1_
Definition BilinearInterpolation.h:775
KeyType const & getOutsideReferencePoint_1() const
Accessor. See setMapping().
Definition BilinearInterpolation.h:737
KeyType const & getOffset_0() const
Accessor. "Offset" is the point (in "outside" units) which corresponds to "Data(0,...
Definition BilinearInterpolation.h:599
~BilinearInterpolation()
Destructor.
Definition BilinearInterpolation.h:115
KeyType outside_1_
Definition BilinearInterpolation.h:779
void setScale_1(KeyType const &scale)
Accessor. "Scale" is the difference (in "outside" units) between consecutive entries in "Data".
Definition BilinearInterpolation.h:593
ContainerType const & getData() const
Returns the internal random access container storing the data.
Definition BilinearInterpolation.h:491
KeyType const & getOutsideReferencePoint_0() const
Accessor. See setMapping().
Definition BilinearInterpolation.h:731
KeyType key2index_1(KeyType pos) const
The transformation from "outside" to "inside" coordinates.
Definition BilinearInterpolation.h:544
void setOffset_0(KeyType const &offset)
Accessor. "Offset" is the point (in "outside" units) which corresponds to "Data(0,...
Definition BilinearInterpolation.h:616
KeyType index2key_1(KeyType pos) const
The transformation from "inside" to "outside" coordinates.
Definition BilinearInterpolation.h:559
KeyType supportMin_0() const
Lower boundary of the support, in "outside" coordinates.
Definition BilinearInterpolation.h:743
KeyType key2index_0(KeyType pos) const
The transformation from "outside" to "inside" coordinates.
Definition BilinearInterpolation.h:521
void setScale_0(KeyType const &scale)
Accessor. "Scale" is the difference (in "outside" units) between consecutive entries in "Data".
Definition BilinearInterpolation.h:583
A 2D matrix class with efficient buffer access for NumPy interoperability.
Definition Matrix.h:35
Size cols() const
Number of columns.
Definition Matrix.h:84
bool empty() const
Check if matrix is empty.
Definition Matrix.h:90
Size rows() const
Number of rows.
Definition Matrix.h:81
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