GCC Code Coverage Report


Directory: ./
File: tasks/khruev_a_global_opt/common/include/common.hpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 24 27 88.9%
Functions: 2 2 100.0%
Branches: 14 16 87.5%

Line Branch Exec Source
1 #pragma once
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstdint>
6 #include <string>
7 #include <tuple>
8
9 #include "task/include/task.hpp"
10
11 namespace khruev_a_global_opt {
12
13 struct SearchData {
14 int func_id;
15 double ax, bx;
16 double ay, by;
17 double epsilon;
18 int max_iter;
19 double r;
20 };
21
22 struct SearchResult {
23 double x;
24 double y;
25 double value;
26 int iter_count;
27 };
28
29 using InType = SearchData;
30 using OutType = SearchResult;
31 using BaseTask = ppc::task::Task<InType, OutType>;
32 using TestType = std::tuple<std::string, int, double, double, double, double, double>;
33
34 // 1. Кривая Гильберта: переводит t [0,1] -> (x, y) [0,1]x[0,1]
35 // Вспомогательная функция для поворота/отражения квадранта
36 // n: размер текущего квадрата (степень двойки)
37 // x, y: координаты
38 // rx, ry: биты, определяющие квадрант
39 inline void Rotate(uint64_t n, uint64_t &x, uint64_t &y, uint64_t rx, uint64_t ry) {
40 117888 if (ry == 0) {
41
2/2
✓ Branch 0 taken 23859 times.
✓ Branch 1 taken 45101 times.
68960 if (rx == 1) {
42 23859 x = n - 1 - x;
43 23859 y = n - 1 - y;
44 }
45 // Swap x и y
46 uint64_t t = x;
47 x = y;
48 y = t;
49 }
50 }
51
52 // 1. Кривая Гильберта: переводит t [0,1] -> (x, y) [0,1]x[0,1]
53 // Используем 32-битный порядок кривой (сетка 2^32 x 2^32), что покрывает точность double
54
2/2
✓ Branch 0 taken 3644 times.
✓ Branch 1 taken 40 times.
3684 inline void D2xy(double t, double &x, double &y) {
55 // Ограничиваем t диапазоном [0, 1]
56 t = std::max(t, 0.0);
57 t = std::min(t, 1.0);
58
59 // Порядок кривой N = 32. Всего точек 2^64 (влезает в uint64_t).
60 // Масштабируем t [0, 1] в целое число s [0, 2^64 - 1]
61 // Используем (2^64 - 1) как множитель.
62 const auto max_dist = static_cast<uint64_t>(-1);
63 const double two_to_64 = ldexp(1.0, 64);
64 3684 double val = t * two_to_64;
65 uint64_t s = 0;
66
2/2
✓ Branch 0 taken 3644 times.
✓ Branch 1 taken 40 times.
3684 if (val >= two_to_64) {
67 s = max_dist;
68 } else {
69 3644 s = static_cast<uint64_t>(val);
70 }
71
72 uint64_t ix = 0;
73 uint64_t iy = 0;
74
75 // Итеративный алгоритм от младших битов к старшим (bottom-up)
76 // n - это размер под-квадрата на текущем уровне
77
2/2
✓ Branch 0 taken 117888 times.
✓ Branch 1 taken 3684 times.
121572 for (uint64_t nn = 1; nn < (1ULL << 32); nn <<= 1) {
78 117888 uint64_t rx = 1 & (s / 2);
79
2/2
✓ Branch 0 taken 68960 times.
✓ Branch 1 taken 48928 times.
117888 uint64_t ry = 1 & (s ^ rx);
80
81 Rotate(nn, ix, iy, rx, ry);
82
83 117888 ix += nn * rx;
84 117888 iy += nn * ry;
85
86 117888 s /= 4;
87 }
88
89 // Нормализуем обратно в [0, 1]
90 // Делим на 2^32 (размер сетки)
91 const double scale = 1.0 / 4294967296.0; // 1.0 / 2^32
92 3684 x = static_cast<double>(ix) * scale;
93 3684 y = static_cast<double>(iy) * scale;
94 3684 }
95
96
4/6
✓ Branch 0 taken 911 times.
✓ Branch 1 taken 911 times.
✓ Branch 2 taken 911 times.
✓ Branch 3 taken 911 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3644 inline double TargetFunction(int id, double x, double y) {
97 if (id == 1) {
98 // квадратичная
99 911 return ((x - 0.5) * (x - 0.5)) + ((y - 0.5) * (y - 0.5));
100 }
101 if (id == 2) {
102 // Rastrigin-like
103 constexpr double kA = 10.0;
104 constexpr double kTwoPi = 6.2831853071795864769;
105 911 return (2.0 * kA) + ((x * x) - (kA * std::cos(kTwoPi * x))) + ((y * y) - (kA * std::cos(kTwoPi * y)));
106 }
107 if (id == 3) {
108 // BoothFunc
109 911 const double t1 = x + (2.0 * y) - 7.0;
110 911 const double t2 = (2.0 * x) + y - 5.0;
111 911 return (t1 * t1) + (t2 * t2);
112 }
113 if (id == 4) {
114 // MatyasFunc
115 911 return (0.26 * ((x * x) + (y * y))) - (0.48 * x * y);
116 }
117 if (id == 5) { // Himme
118 const double t1 = ((x * x) + y - 11.0);
119 const double t2 = (x + (y * y) - 7.0);
120 return (t1 * t1) + (t2 * t2);
121 }
122
123 return 0.0;
124 }
125
126 // Структура для хранения испытаний
127 struct Trial {
128 double x; // координата на отрезке [0, 1]
129 double z; // значение функции
130 int id; // исходный индекс
131
132 bool operator<(const Trial &other) const {
133 return x < other.x;
134 }
135 };
136
137 } // namespace khruev_a_global_opt
138