Ocean
Loading...
Searching...
No Matches
Median.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_BASE_MEDIAN_H
9#define META_OCEAN_BASE_MEDIAN_H
10
11#include "ocean/base/Base.h"
12#include "ocean/base/Memory.h"
13
14namespace Ocean
15{
16
17/**
18 * This class implements a median determination value.
19 * @ingroup base
20 */
21class Median
22{
23 public:
24
25 /**
26 * Returns the median of two given values (the lower of both).
27 * Beware: In the case one of the given values is not a number (nan) the result may be arbitrary as the comparison operator is not defined for such values.
28 * @param v0 First value
29 * @param v1 Second value
30 * @return Resulting median
31 * @tparam T Data type of the data elements
32 */
33 template <typename T>
34 static inline T median2(const T& v0, const T& v1);
35
36 /**
37 * Returns the median of three given values.
38 * Beware: In the case one of the given values is not a number (nan) the result may be arbitrary as the comparison operator is not defined for such values.
39 * @param v0 First value
40 * @param v1 Second value
41 * @param v2 Third value
42 * @return Resulting median
43 * @tparam T Data type of the data elements
44 */
45 template <typename T>
46 static inline T median3(const T& v0, const T& v1, const T& v2);
47
48 /**
49 * Returns the median of four given values (the second smallest value).
50 * Beware: In the case one of the given values is not a number (nan) the result may be arbitrary as the comparison operator is not defined for such values.
51 * @param v0 First value
52 * @param v1 Second value
53 * @param v2 Third value
54 * @param v3 Fourth value
55 * @return Resulting median
56 * @tparam T Data type of the data elements
57 */
58 template <typename T>
59 static inline T median4(const T& v0, const T& v1, const T& v2, const T& v3);
60
61 /**
62 * Returns the median of five given values.
63 * Beware: In the case one of the given values is not a number (nan) the result may be arbitrary as the comparison operator is not defined for such values.
64 * @param v0 First value
65 * @param v1 Second value
66 * @param v2 Third value
67 * @param v3 Fourth value
68 * @param v4 Fifth value
69 * @return Resulting median
70 * @tparam T Data type of the data elements
71 */
72 template <typename T>
73 static inline T median5(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4);
74
75 /**
76 * Returns the median value in a given data array.
77 * If the given number is even, the median value is selected left from the exact center.<br>
78 * Beware: In the case one of the given values is not a number (nan) the result may be arbitrary as the comparison operator is not defined for such values.
79 * @param values Array with values that will be reordered during the execution, must be valid
80 * @param number Number of values, with range [1, infinity)
81 * @return The median value out of 'values'
82 * @tparam T Type of the data for that the median has to be determined
83 */
84 template <typename T>
85 static T median(T* values, const size_t number);
86
87 /**
88 * Returns the median value in a given data array.
89 * If the given number is even, the median value is selected left from the exact center.<br>
90 * Beware: In the case one of the given values is not a number (nan) the result may be arbitrary as the comparison operator is not defined for such values.
91 * @param values Array with values from which the median will be determined, must be valid
92 * @param number Number of values, with range [1, infinity)
93 * @return The median value out of 'values'
94 * @tparam T Type of the data for that the median has to be determined
95 */
96 template <typename T>
97 static T constMedian(const T* values, const size_t number);
98};
99
100template <typename T>
101inline T Median::median2(const T& v0, const T& v1)
102{
103 return v0 < v1 ? v0 : v1;
104}
105
106template <typename T>
107inline T Median::median3(const T& v0, const T& v1, const T& v2)
108{
109 if (v0 < v1)
110 {
111 // [ v0 < v1 ]
112
113 if (v2 < v0)
114 {
115 // [ v2 < v0 < v1]
116 return v0;
117 }
118 else // v2 >= v0
119 {
120 // [ v0 < v1,v2 ]
121
122 if (v1 < v2)
123 return v1;
124 else
125 return v2;
126 }
127 }
128 else // v0 >= v1
129 {
130 // [ v1 < v0 ]
131
132 if (v2 < v1)
133 {
134 // [ v2 < v1 < v0 ]
135
136 return v1;
137 }
138 else // v2 >= v1
139 {
140 // [ v1 < v0,v2 ]
141
142 if (v0 < v2)
143 return v0;
144 else
145 return v2;
146 }
147 }
148}
149
150template <typename T>
151inline T Median::median4(const T& v0, const T& v1, const T& v2, const T& v3)
152{
153 // v0, v1, v2, v3
154 if (v0 < v1)
155 {
156 // v0 < v1 | v2, v3
157
158 if (v0 < v2)
159 {
160 // v0 < v1,v2 | v3
161
162 if (v0 < v3)
163 {
164 // v0 < v1,v2,v3
165
166 if (v1 < v2)
167 {
168 // v0 < v1 < v2 | v0 < v3
169
170 if (v2 < v3)
171 {
172 // v0 < v1 < v2 < v3
173 return v1;
174 }
175 else // v3 < v2
176 {
177 // v0 < v1 < v2 | v0 < v3 | v3 < v2
178
179 if (v3 < v1)
180 {
181 // v0 < v3 < v1 < v2
182 return v3;
183 }
184 else // v1 < v3
185 {
186 // v0 < v1 < v3 < v2
187 return v1;
188 }
189 }
190 }
191 else // v2 < v1
192 {
193 // v0 < v1,v2,v3 | v2 < v1
194
195 if (v2 < v3)
196 {
197 // v0 < v1,v2,v3 | v2 < v1,v3
198 return v2;
199 }
200 else // v3 < v2
201 {
202 // v0 < v1,v2,v3 | v3 < v2 < v1
203 return v3;
204 }
205 }
206 }
207 else // v3 < v0
208 {
209 // v3 < v0 < v1,v2
210 return v0;
211 }
212 }
213 else // v2 < v0
214 {
215 // v2 < v0 < v1 | v3
216
217 if (v3 < v2)
218 {
219 // v3 < v2 < v0 < v1
220 return v2;
221 }
222 else // v2 < v3
223 {
224 // v2 < v0 < v1 | v2 < v3
225
226 if (v0 < v3)
227 {
228 // v2 < v0 < v1, v3
229 return v0;
230 }
231 else // v3 < v0
232 {
233 // v2 < v3 < v0 < v1
234 return v3;
235 }
236 }
237 }
238 }
239 else // v1 < v0
240 {
241 // v1 < v0 | v2, v3
242
243 if (v2 < v1)
244 {
245 // v2 < v1 < v0 | v3
246
247 if (v3 < v2)
248 {
249 // v3 < v2 < v1 < v0
250 return v2;
251 }
252 else // v2 < v3
253 {
254 // v2 < v1 < v0 | v2 < v3
255
256 if (v1 < v3)
257 {
258 // v2 < v1 < v0,v3
259 return v1;
260 }
261 else // v3 < v1
262 {
263 // v2 < v3 < v1 < v0
264 return v3;
265 }
266 }
267 }
268 else // v1 < v2
269 {
270 // v1 < v0,v2 | v3
271
272 if (v0 < v2)
273 {
274 // v1 < v0 < v2 | v3
275
276 if (v3 < v1)
277 {
278 // v3 < v1 < v0 < v2
279 return v1;
280 }
281 else // v1 < v3
282 {
283 // v1 < v0 < v2 | v1 < v3
284
285 if (v0 < v3)
286 {
287 // v1 < v0 < v2,v3
288 return v0;
289 }
290 else // v3 < v0
291 {
292 // v1 < v3 < v0 < v2
293 return v3;
294 }
295 }
296 }
297 else // v2 < v0
298 {
299 // v1 < v2 < v0 | v3
300
301 if (v3 < v1)
302 {
303 // v3 < v1 < v2 < v0
304 return v1;
305 }
306 else // v1 < v3
307 {
308 // v1 < v2 < v0 | v1 < v3
309
310 if (v2 < v3)
311 {
312 // v1 < v2 < v0, v3
313 return v2;
314 }
315 else // v3 < v2
316 {
317 // v1 < v3 < v2 < v0
318 return v3;
319 }
320 }
321 }
322 }
323 }
324}
325
326template <typename T>
327inline T Median::median5(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4)
328{
329 // v0, v1, v2, v3, v4
330 if (v0 < v1)
331 {
332 // v0 < v1 | v2, v3, v4
333
334 if (v0 < v2)
335 {
336 // v0 < v1,v2 | v3, v4
337
338 if (v0 < v3)
339 {
340 // v0 < v1,v2,v3 | v4
341
342 if (v0 < v4)
343 {
344 // v0 < v1,v2,v3,v4
345
346 if (v1 < v2)
347 {
348 // v0 < v1 < v2 | v0 < v3,v4
349
350 if (v2 < v3)
351 {
352 // v0 < v1 < v2 < v3 | v0 < v4
353
354 if (v3 < v4)
355 {
356 // v0 < v1 < v2 < v3 < v4
357 return v2;
358 }
359 else // v4 < v3
360 {
361 // v0 < v1 < v2 < v3 | v0 < v4 < v3
362
363 if (v4 < v2)
364 {
365 // v0 < v1 < v2 < v3 | v0 < v4 < v2
366
367 if (v4 < v1)
368 {
369 // v0 < v4 < v1 < v2 < v3
370 return v1;
371 }
372 else // v1 < v4
373 {
374 // v0 < v1 < v4 < v2 < v3
375 return v4;
376 }
377 }
378 else // v2 < v4
379 {
380 // v0 < v1 < v2 < v4 < v3
381 return v2;
382 }
383 }
384 }
385 else // v3 < v2
386 {
387 // v0 < v1 < v2 | v0 < v3,v4 | v3 < v2
388
389 if (v3 < v1)
390 {
391 // v0 < v3 < v1 < v2 | v0 < v4
392
393 if (v4 < v3)
394 {
395 // v0 < v4 < v3 < v1 < v2
396 return v3;
397 }
398 else // v3 < v4
399 {
400 // v0 < v3 < v1 < v2 | v3 < v4
401
402 if (v4 < v1)
403 {
404 // v0 < v3 < v4 < v1 < v2
405 return v4;
406 }
407 else // v1 < v4
408 {
409 // v0 < v3 < v1 < v2,v4
410 return v1;
411 }
412 }
413 }
414 else // v1 < v3
415 {
416 // v0 < v1 < v3 < v2 | v0 < v4
417
418 if (v1 < v4)
419 {
420 // v0 < v1 < v3 < v2 | v1 < v4
421
422 if (v3 < v4)
423 {
424 // v0 < v1 < v3 < v2, v4
425 return v3;
426 }
427 else // v4 < v3
428 {
429 // v0 < v1 < v4 < v3 < v2
430 return v4;
431 }
432 }
433 else // v4 < v1
434 {
435 // v0 < v4 < v1 < v3 < v2
436 return v1;
437 }
438 }
439 }
440 }
441 else // v2 < v1
442 {
443 // v0 < v1,v2,v3,v4 | v2 < v1
444
445 if (v2 < v3)
446 {
447 // v0 < v1,v2,v3,v4 | v2 < v1,v3
448
449 if (v2 < v4)
450 {
451 // v0 < v2 < v1,v3,v4
452
453 if (v1 < v3)
454 {
455 // v0 < v2 < v1,v3,v4 | v1 < v3
456
457 if (v1 < v4)
458 {
459 // v0 < v2 < v1 < v3,v4
460 return v1;
461 }
462 else // v4 < v1
463 {
464 // v0 < v2 < v4 < v1 < v3
465 return v4;
466 }
467 }
468 else // v3 < v1
469 {
470 // v0 < v2 < v1,v3,v4 | v3 < v1
471
472 if (v3 < v4)
473 {
474 // v0 < v2 < v3 < v1,v4
475 return v3;
476 }
477 else // v4 < v3
478 {
479 // v0 < v2 < v4 < v3 < v1
480 return v4;
481 }
482 }
483 }
484 else // v4 < v2
485 {
486 // v0 < v4 < v2 < v1,v3
487 return v2;
488 }
489 }
490 else // v3 < v2
491 {
492 // v0 < v1,v2,v3,v4 | v3 < v2 < v1
493
494 if (v3 < v4)
495 {
496 // v0 < v3 < v2 < v1 | v3 < v4
497
498 if (v2 < v4)
499 {
500 // v0 < v3 < v2 < v1,v4
501 return v2;
502 }
503 else // v4 < v2
504 {
505 // v0 < v3 < v4 < v2 < v1
506 return v4;
507 }
508 }
509 else // v4 < v3
510 {
511 // v0 < v4 < v3 < v2 < v1
512 return v3;
513 }
514 }
515 }
516 }
517 else // v4 < v0
518 {
519 // v4 < v0 < v1,v2,v3
520
521 if (v1 < v2)
522 {
523 // v4 < v0 < v1,v2,v3 | v1 < v2
524
525 if (v1 < v3)
526 {
527 // v4 < v0 < v1 < v2,v3
528 return v1;
529 }
530 else // v3 < v1
531 {
532 // v4 < v0 < v3 < v1 < v2
533 return v3;
534 }
535 }
536 else // v2 < v1
537 {
538 // v4 < v0 < v1,v2,v3 | v2 < v1
539
540 if (v2 < v3)
541 {
542 // v4 < v0 < v2 < v1,v3
543 return v2;
544 }
545 else // v3 < v2
546 {
547 // v4 < v0 < v3 < v2 < v1
548 return v3;
549 }
550 }
551 }
552 }
553 else // v3 < v0
554 {
555 // v3 < v0 < v1,v2 | v4
556
557 if (v0 < v4)
558 {
559 // v3 < v0 < v1,v2,v4
560
561 if (v1 < v2)
562 {
563 // v3 < v0 < v1,v2,v4 | v1 < v2
564
565 if (v1 < v4)
566 {
567 // v3 < v0 < v1 < v2,v4
568 return v1;
569 }
570 else // v4 < v1
571 {
572 // v3 < v0 < v4 < v1 < v2
573 return v4;
574 }
575 }
576 else // v2 < v1
577 {
578 // v3 < v0 < v1,v2,v4 | v2 < v1
579
580 if (v2 < v4)
581 {
582 // v3 < v0 < v2 < v1,v4
583 return v2;
584 }
585 else // v4 < v2
586 {
587 // v3 < v0 < v4 < v2 < v1
588 return v4;
589 }
590 }
591 }
592 else // v4 < v0
593 {
594 // v3,v4 < v0 < v1,v2
595 return v0;
596 }
597 }
598 }
599 else // v2 < v0
600 {
601 // v2 < v0 < v1 | v3, v4
602
603 if (v3 < v2)
604 {
605 // v3 < v2 < v0 < v1 | v4
606
607 if (v0 < v4)
608 {
609 // v3 < v2 < v0 < v1,v4
610 return v0;
611 }
612 else // v4 < v0
613 {
614 // v3 < v2 < v0 < v1 | v4 < v0
615
616 if (v4 < v2)
617 {
618 // v3,v4 < v2 < v0 < v1
619 return v2;
620
621 }
622 else // v2 < v4
623 {
624 // v3 < v2 < v4 < v0 < v1
625 return v4;
626 }
627 }
628 }
629 else // v2 < v3
630 {
631 // v2 < v0 < v1 | v2 < v3 | v4
632
633 if (v4 < v2)
634 {
635 // v4 < v2 < v0 < v1 | v2 < v3
636
637 if (v0 < v3)
638 {
639 // v4 < v2 < v0 < v1, v3
640 return v0;
641 }
642 else // v3 < v0
643 {
644 // v4 < v2 < v3 < v0 < v1
645 return v3;
646 }
647 }
648 else // v2 < v4
649 {
650 // v2 < v0 < v1 | v2 < v3, v4
651
652 if (v4 < v0)
653 {
654 // v2 < v4 < v0 < v1 | v2 < v3
655
656 if (v4 < v3)
657 {
658 // v2 < v4 < v0 < v1 | v4 < v3
659
660 if (v0 < v3)
661 {
662 // v2 < v4 < v0 < v1,v3
663 return v0;
664 }
665 else // v3 < v0
666 {
667 // v2 < v4 < v3 < v0 < v1
668 return v3;
669 }
670 }
671 else // v3 < v4
672 {
673 // v2 < v3 < v4 < v0 < v1
674 return v4;
675 }
676 }
677 else // v0 < v4
678 {
679 // v2 < v0 < v1,v4 | v2 < v3
680
681 if (v0 < v3)
682 {
683 // v2 < v0 < v1,v4,v3
684
685 if (v1 < v4)
686 {
687 // v2 < v0 < v1,v4,v3 | v1 < v4
688
689 if (v1 < v3)
690 {
691 // v2 < v0 < v1 < v3,v4
692 return v1;
693 }
694 else // v3 < v1
695 {
696 // v2 < v0 < v3 < v1 < v4
697 return v3;
698 }
699 }
700 else // v4 < v1
701 {
702 // v2 < v0 < v1,v4,v3 | v4 < v1
703
704 if (v4 < v3)
705 {
706 // v2 < v0 < v4 < v1,v3
707 return v4;
708 }
709 else // v3 < v4
710 {
711 // v2 < v0 < v3 < v4 < v1
712 return v3;
713 }
714 }
715 }
716 else // v3 < v0
717 {
718 // v2 < v3 < v0 < v1,v4
719 return v0;
720 }
721 }
722 }
723 }
724 }
725 }
726 else // v1 < v0
727 {
728 // v1 < v0 | v2, v3, v4
729
730 if (v2 < v1)
731 {
732 // v2 < v1 < v0 | v3, v4
733
734 if (v3 < v2)
735 {
736 // v3 < v2 < v1 < v0 | v4
737
738 if (v4 < v3)
739 {
740 // v4 < v3 < v2 < v1 < v0
741 return v2;
742 }
743 else // v3 < v4
744 {
745 // v3 < v2 < v1 < v0 | v3 < v4
746
747 if (v2 < v4)
748 {
749 // v3 < v2 < v1 < v0 | v2 < v4
750
751 if (v1 < v4)
752 {
753 // v3 < v2 < v1 < v0,v4
754 return v1;
755 }
756 else // v4 < v1
757 {
758 // v3 < v2 < v4 < v1 < v0
759 return v4;
760 }
761 }
762 else // v4 < v2
763 {
764 // v3 < v4 < v2 < v1 < v0
765 return v2;
766 }
767 }
768 }
769 else // v2 < v3
770 {
771 // v2 < v1 < v0 | v2 < v3 | v4
772
773 if (v4 < v2)
774 {
775 // v4 < v2 < v1 < v0 | v2 < v3
776
777 if (v1 < v3)
778 {
779 // v4 < v2 < v1 < v0,v3
780 return v1;
781 }
782 else // v3 < v1
783 {
784 // v4 < v2 < v3 < v1 < v0
785 return v3;
786 }
787 }
788 else // v2 < v4
789 {
790 // v2 < v1 < v0 | v2 < v3,v4
791
792 if (v1 < v3)
793 {
794 // v2 < v1 < v0,v3 | v2 < v4
795
796 if (v1 < v4)
797 {
798 // v2 < v1 < v0,v3,v4
799
800 if (v0 < v3)
801 {
802 // v2 < v1 < v0,v3,v4 | v0 < v3
803
804 if (v0 < v4)
805 {
806 // v2 < v1 < v0 < v3,v4
807 return v0;
808 }
809 else // v4 < v0
810 {
811 // v2 < v1 < v4 < v0 < v3
812 return v4;
813 }
814 }
815 else // v3 < v0
816 {
817 // v2 < v1 < v0,v3,v4 | v3 < v0
818
819 if (v3 < v4)
820 {
821 // v2 < v1 < v3 < v0,v4
822 return v3;
823 }
824 else // v4 < v3
825 {
826 // v2 < v1 < v4 < v3 < v0
827 return v4;
828 }
829 }
830 }
831 else // v4 < v1
832 {
833 // v2 < v4 < v1 < v0,v3
834 return v1;
835 }
836 }
837 else // v3 < v1
838 {
839 // v2 < v3 < v1 < v0 | v2 < v4
840
841 if (v3 < v4)
842 {
843 // v2 < v3 < v1 < v0 | v3 < v4
844
845 if (v1 < v4)
846 {
847 // v2 < v3 < v1 < v0,v4
848 return v1;
849 }
850 else // v4 < v1
851 {
852 // v2 < v3 < v4 < v1 < v0
853 return v4;
854 }
855 }
856 else // v4 < v3
857 {
858 // v2 < v4 < v3 < v1 < v0
859 return v3;
860 }
861 }
862 }
863 }
864 }
865 else // v1 < v2
866 {
867 // v1 < v0,v2 | v3, v4
868
869 if (v0 < v2)
870 {
871 // v1 < v0 < v2 | v3, v4
872
873 if (v3 < v1)
874 {
875 // v3 < v1 < v0 < v2 | v4
876
877 if (v4 < v3)
878 {
879 // v4 < v3 < v1 < v0 < v2
880 return v1;
881 }
882 else // v3 < v4
883 {
884 // v3 < v1 < v0 < v2 | v3 < v4
885
886 if (v1 < v4)
887 {
888 // v3 < v1 < v0 < v2 | v1 < v4
889
890 if (v0 < v4)
891 {
892 // v3 < v1 < v0 < v2,v4
893 return v0;
894 }
895 else // v4 < v0
896 {
897 // v3 < v1 < v4 < v0 < v2
898 return v4;
899 }
900 }
901 else // v4 < v1
902 {
903 // v3 < v4 < v1 < v0 < v2
904 return v1;
905 }
906 }
907 }
908 else // v1 < v3
909 {
910 // v1 < v0 < v2 | v1 < v3 | v4
911
912 if (v4 < v1)
913 {
914 // v4 < v1 < v0 < v2 | v1 < v3
915
916 if (v0 < v3)
917 {
918 // v4 < v1 < v0 < v2,v3
919 return v0;
920 }
921 else // v3 < v0
922 {
923 // v4 < v1 < v3 < v0 < v2
924 return v3;
925 }
926 }
927 else // v1 < v4
928 {
929 // v1 < v0 < v2 | v1 < v3,v4
930
931 if (v0 < v3)
932 {
933 // v1 < v0 < v2,v3 | v1 < v4
934
935 if (v0 < v4)
936 {
937 // v1 < v0 < v2,v3,v4
938
939 if (v2 < v3)
940 {
941 // v1 < v0 < v2,v3,v4 | v2 < v3
942
943 if (v2 < v4)
944 {
945 // v1 < v0 < v2 < v3,v4
946 return v2;
947 }
948 else // v4 < v2
949 {
950 // v1 < v0 < v4 < v2 < v3
951 return v4;
952 }
953 }
954 else // v3 < v2
955 {
956 // v1 < v0 < v2,v3,v4 | v3 < v2
957
958 if (v3 < v4)
959 {
960 // v1 < v0 < v3 < v2,v4
961 return v3;
962 }
963 else // v4 < v3
964 {
965 // v1 < v0 < v4 < v3 < v2
966 return v4;
967 }
968 }
969 }
970 else // v4 < v0
971 {
972 // v1 < v4 < v0 < v2,v3
973 return v0;
974 }
975 }
976 else // v3 < v0
977 {
978 // v1 < v3 < v0 < v2 | v1 < v4
979
980 if (v3 < v4)
981 {
982 // v1 < v3 < v0 < v2 | v3 < v4
983
984 if (v0 < v4)
985 {
986 // v1 < v3 < v0 < v2, v4
987 return v0;
988 }
989 else // v4 < v0
990 {
991 // v1 < v3 < v4 < v0 < v2
992 return v4;
993 }
994 }
995 else // v4 < v3
996 {
997 // v1 < v4 < v3 < v0 < v2
998 return v3;
999 }
1000 }
1001 }
1002 }
1003 }
1004 else // v2 < v0
1005 {
1006 // v1 < v2 < v0 | v3, v4
1007
1008 if (v3 < v1)
1009 {
1010 // v3 < v1 < v2 < v0 | v4
1011
1012 if (v4 < v3)
1013 {
1014 // v4 < v3 < v1 < v2 < v0
1015 return v1;
1016 }
1017 else // v3 < v4
1018 {
1019 // v3 < v1 < v2 < v0 | v3 < v4
1020
1021 if (v1 < v4)
1022 {
1023 // v3 < v1 < v2 < v0 | v1 < v4
1024
1025 if (v2 < v4)
1026 {
1027 // v3 < v1 < v2 < v0,v4
1028 return v2;
1029 }
1030 else // v4 < v2
1031 {
1032 // v3 < v1 < v4 < v2 < v0
1033 return v4;
1034 }
1035 }
1036 else // v4 < v1
1037 {
1038 // v3 < v4 < v1 < v2 < v0
1039 return v1;
1040 }
1041 }
1042 }
1043 else // v1 < v3
1044 {
1045 // v1 < v2 < v0 | v1 < v3 | v4
1046
1047 if (v4 < v1)
1048 {
1049 // v4 < v1 < v2 < v0 | v1 < v3
1050
1051 if (v2 < v3)
1052 {
1053 // v4 < v1 < v2 < v0, v3
1054 return v2;
1055 }
1056 else // v3 < v2
1057 {
1058 // v4 < v1 < v3 < v2 < v0
1059 return v3;
1060 }
1061 }
1062 else // v1 < v4
1063 {
1064 // v1 < v2 < v0 | v1 < v3, v4
1065
1066 if (v2 < v3)
1067 {
1068 // v1 < v2 < v0,v3 | v1 < v4
1069
1070 if (v2 < v4)
1071 {
1072 // v1 < v2 < v0,v3,v4
1073
1074 if (v0 < v3)
1075 {
1076 // v1 < v2 < v0,v3,v4 | v0 < v3
1077
1078 if (v0 < v4)
1079 {
1080 // v1 < v2 < v0 < v3,v4
1081 return v0;
1082 }
1083 else // v4 < v0
1084 {
1085 // v1 < v2 < v4 < v0 < v3
1086 return v4;
1087 }
1088 }
1089 else // v3 < v0
1090 {
1091 // v1 < v2 < v0,v3,v4 | v3 < v0
1092
1093 if (v3 < v4)
1094 {
1095 // v1 < v2 < v3 < v0,v4
1096 return v3;
1097 }
1098 else // v4 < v3
1099 {
1100 // v1 < v2 < v4 < v3 < v0
1101 return v4;
1102 }
1103 }
1104 }
1105 else // v4 < v2
1106 {
1107 // v1 < v4 < v2 < v0,v3
1108 return v2;
1109 }
1110 }
1111 else // v3 < v2
1112 {
1113 // v1 < v3 < v2 < v0 | v1 < v4
1114
1115 if (v3 < v4)
1116 {
1117 // v1 < v3 < v2 < v0 | v3 < v4
1118
1119 if (v2 < v4)
1120 {
1121 // v1 < v3 < v2 < v0, v4
1122 return v2;
1123 }
1124 else // v4 < v2
1125 {
1126 // v1 < v3 < v4 < v2 < v0
1127 return v4;
1128 }
1129 }
1130 else // v4 < v3
1131 {
1132 // v1 < v4 < v3 < v2 < v0
1133 return v3;
1134 }
1135 }
1136 }
1137 }
1138 }
1139 }
1140 }
1141}
1142
1143template <typename T>
1144T Median::median(T* values, const size_t number)
1145{
1146 ocean_assert(values && number > 0);
1147
1148 size_t low = 0;
1149 size_t high = number - 1;
1150 size_t median = (low + high) >> 1;
1151
1152 size_t ll, hh, middle;
1153
1154 while (true)
1155 {
1156 // only one element
1157 if (high <= low)
1158 return values[median];
1159
1160 // only two elements
1161 if (high == low + 1)
1162 {
1163 if (values[low] > values[high])
1164 std::swap(values[low], values[high]);
1165
1166 return values[median];
1167 }
1168
1169 middle = (low + high) / 2;
1170
1171 if (values[middle] > values[high])
1172 std::swap(values[middle], values[high]);
1173
1174 if (values[low] > values[high])
1175 std::swap(values[low], values[high]);
1176
1177 if (values[middle] > values[low])
1178 std::swap(values[middle], values[low]);
1179
1180 std::swap(values[middle], values[low + 1]);
1181
1182 ll = low + 1;
1183 hh = high;
1184
1185 while (true)
1186 {
1187 while (ll < number && values[low] > values[++ll]); // we need the explicit out-of-range check for not-a-number (nan) elements
1188
1189 while (hh > 0 && values[--hh] > values[low]);
1190
1191 if (hh < ll)
1192 break;
1193
1194 std::swap(values[ll], values[hh]);
1195 }
1196
1197 std::swap(values[low], values[hh]);
1198
1199 if (hh <= median)
1200 low = ll;
1201
1202 if (hh >= median)
1203 high = hh - 1;
1204 }
1205}
1206
1207template <typename T>
1208T Median::constMedian(const T* values, const size_t number)
1209{
1210 ocean_assert(values != nullptr && number > 0);
1211
1212 if (number == 0)
1213 return 1;
1214
1215 Memory memory = Memory::create<T>(number);
1216
1217 if (memory.data() == nullptr)
1218 {
1219 ocean_assert(false && "Out of memory");
1220 return 1;
1221 }
1222
1223 memcpy(memory.data<T>(), values, sizeof(T) * number);
1224 const T result = median(memory.data<T>(), number);
1225
1226 return result;
1227}
1228
1229}
1230
1231#endif // META_OCEAN_BASE_MEDIAN_H
This class implements a median determination value.
Definition Median.h:22
static T median4(const T &v0, const T &v1, const T &v2, const T &v3)
Returns the median of four given values (the second smallest value).
Definition Median.h:151
static T median5(const T &v0, const T &v1, const T &v2, const T &v3, const T &v4)
Returns the median of five given values.
Definition Median.h:327
static T median(T *values, const size_t number)
Returns the median value in a given data array.
Definition Median.h:1144
static T median2(const T &v0, const T &v1)
Returns the median of two given values (the lower of both).
Definition Median.h:101
static T median3(const T &v0, const T &v1, const T &v2)
Returns the median of three given values.
Definition Median.h:107
static T constMedian(const T *values, const size_t number)
Returns the median value in a given data array.
Definition Median.h:1208
This class implements an object able to allocate memory.
Definition base/Memory.h:22
void * data()
Returns the pointer to the writable memory which is allocated by this object.
Definition base/Memory.h:303
The namespace covering the entire Ocean framework.
Definition Accessor.h:15