| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "kulik_a_radix_sort_double_simple_merge/seq/include/ops_seq.hpp" | ||
| 2 | |||
| 3 | #include <algorithm> | ||
| 4 | #include <cmath> | ||
| 5 | #include <cstddef> | ||
| 6 | #include <cstdint> | ||
| 7 | #include <utility> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "kulik_a_radix_sort_double_simple_merge/common/include/common.hpp" | ||
| 11 | |||
| 12 | namespace kulik_a_radix_sort_double_simple_merge { | ||
| 13 | |||
| 14 | ✗ | KulikARadixSortDoubleSimpleMergeSEQ::KulikARadixSortDoubleSimpleMergeSEQ(const InType &in) { | |
| 15 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 16 | ✗ | GetInput() = in; | |
| 17 | ✗ | } | |
| 18 | |||
| 19 | ✗ | bool KulikARadixSortDoubleSimpleMergeSEQ::ValidationImpl() { | |
| 20 | ✗ | return (!GetInput().empty()); | |
| 21 | } | ||
| 22 | |||
| 23 | ✗ | bool KulikARadixSortDoubleSimpleMergeSEQ::PreProcessingImpl() { | |
| 24 | ✗ | return true; | |
| 25 | } | ||
| 26 | |||
| 27 | ✗ | double *KulikARadixSortDoubleSimpleMergeSEQ::LSDSortBytes(double *arr, double *buffer, size_t size) { | |
| 28 | double *parr = arr; | ||
| 29 | double *pbuffer = buffer; | ||
| 30 | ✗ | for (uint64_t byte = 0; byte < sizeof(double); ++byte) { | |
| 31 | ✗ | std::vector<uint64_t> count(256, 0); | |
| 32 | auto *bytes = reinterpret_cast<unsigned char *>(parr); | ||
| 33 | ✗ | for (size_t i = 0; i < size; ++i) { | |
| 34 | ✗ | count[bytes[(sizeof(double) * i) + byte]]++; | |
| 35 | } | ||
| 36 | uint64_t pos = 0; | ||
| 37 | ✗ | for (uint64_t i = 0; i < 256; ++i) { | |
| 38 | ✗ | uint64_t temp = count[i]; | |
| 39 | ✗ | count[i] = pos; | |
| 40 | ✗ | pos += temp; | |
| 41 | } | ||
| 42 | ✗ | for (size_t i = 0; i < size; ++i) { | |
| 43 | ✗ | unsigned char byte_value = bytes[(sizeof(double) * i) + byte]; | |
| 44 | ✗ | uint64_t new_pos = count[byte_value]++; | |
| 45 | ✗ | pbuffer[new_pos] = parr[i]; | |
| 46 | } | ||
| 47 | std::swap(parr, pbuffer); | ||
| 48 | } | ||
| 49 | ✗ | return parr; | |
| 50 | } | ||
| 51 | |||
| 52 | ✗ | void KulikARadixSortDoubleSimpleMergeSEQ::AdjustNegativeNumbers(std::vector<double> &arr, size_t size) { | |
| 53 | size_t neg_start = 0; | ||
| 54 | ✗ | while (neg_start < size && arr[neg_start] >= 0.0) { | |
| 55 | ✗ | ++neg_start; | |
| 56 | } | ||
| 57 | ✗ | if (neg_start < size) { | |
| 58 | ✗ | for (size_t i = neg_start, j = size - 1; i < j; ++i, --j) { | |
| 59 | std::swap(arr[i], arr[j]); | ||
| 60 | } | ||
| 61 | ✗ | std::vector<double> temp(size); | |
| 62 | size_t index = 0; | ||
| 63 | ✗ | for (size_t i = neg_start; i < size; ++i) { | |
| 64 | ✗ | temp[index++] = arr[i]; | |
| 65 | } | ||
| 66 | ✗ | for (size_t i = 0; i < neg_start; ++i) { | |
| 67 | ✗ | temp[index++] = arr[i]; | |
| 68 | } | ||
| 69 | arr = std::move(temp); | ||
| 70 | } | ||
| 71 | ✗ | } | |
| 72 | |||
| 73 | ✗ | void KulikARadixSortDoubleSimpleMergeSEQ::LSDSortDouble(std::vector<double> &arr) { | |
| 74 | size_t size = arr.size(); | ||
| 75 | ✗ | std::vector<double> buffer(size); | |
| 76 | ✗ | double *sorted_ptr = LSDSortBytes(arr.data(), buffer.data(), size); | |
| 77 | ✗ | if (sorted_ptr == buffer.data()) { | |
| 78 | std::ranges::copy(buffer, arr.begin()); | ||
| 79 | } | ||
| 80 | ✗ | AdjustNegativeNumbers(arr, size); | |
| 81 | ✗ | } | |
| 82 | |||
| 83 | ✗ | bool KulikARadixSortDoubleSimpleMergeSEQ::RunImpl() { | |
| 84 | ✗ | GetOutput() = GetInput(); | |
| 85 | ✗ | LSDSortDouble(GetOutput()); | |
| 86 | ✗ | return true; | |
| 87 | } | ||
| 88 | |||
| 89 | ✗ | bool KulikARadixSortDoubleSimpleMergeSEQ::PostProcessingImpl() { | |
| 90 | ✗ | return (!GetOutput().empty()); | |
| 91 | } | ||
| 92 | |||
| 93 | } // namespace kulik_a_radix_sort_double_simple_merge | ||
| 94 |