GCC Code Coverage Report


Directory: ./
File: tasks/kruglova_a_2d_multistep_par_opt/seq/src/ops_seq.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 102 102 100.0%
Functions: 13 13 100.0%
Branches: 67 100 67.0%

Line Branch Exec Source
1 #include "kruglova_a_2d_multistep_par_opt/seq/include/ops_seq.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <functional>
7 #include <limits>
8 #include <utility>
9 #include <vector>
10
11 #include "kruglova_a_2d_multistep_par_opt/common/include/common.hpp"
12
13 namespace kruglova_a_2d_multistep_par_opt {
14
15 namespace {
16
17 struct Trial1D {
18 double x;
19 double z;
20
21 2928 Trial1D(double x_val, double z_val) : x(x_val), z(z_val) {}
22 };
23
24 struct Trial2D {
25 double x;
26 double y;
27 double z;
28
29 960 Trial2D(double x_val, double y_val, double z_val) : x(x_val), y(y_val), z(z_val) {}
30 };
31
32 template <typename T>
33 71024 double CalculateM(const std::vector<T> &trials) {
34 71024 double m_max = 0.0;
35
2/2
✓ Branch 0 taken 470440 times.
✓ Branch 1 taken 35512 times.
1011904 for (size_t i = 0; i + 1 < trials.size(); ++i) {
36 940880 const double dx = trials[i + 1].x - trials[i].x;
37
1/2
✓ Branch 0 taken 470440 times.
✗ Branch 1 not taken.
940880 if (dx > 1e-15) {
38 940880 const double dz = std::abs(trials[i + 1].z - trials[i].z);
39 940880 const double ratio = dz / dx;
40 940880 m_max = std::max(ratio, m_max);
41 }
42 }
43 71024 return m_max;
44 }
45
46 34960 size_t FindBestInterval1D(const std::vector<Trial1D> &trials, double m_scaled) {
47 double max_rate = -std::numeric_limits<double>::infinity();
48 size_t best_idx = 0;
49
50
2/2
✓ Branch 0 taken 456640 times.
✓ Branch 1 taken 34960 times.
491600 for (size_t i = 0; i + 1 < trials.size(); ++i) {
51 456640 const double dx = trials[i + 1].x - trials[i].x;
52 456640 const double dz = trials[i + 1].z - trials[i].z;
53
54 456640 const double term1 = m_scaled * dx;
55 456640 const double term2 = (dz * dz) / (m_scaled * dx);
56 456640 const double term3 = 2.0 * (trials[i + 1].z + trials[i].z);
57 456640 const double rate = term1 + term2 - term3;
58
59
2/2
✓ Branch 0 taken 132320 times.
✓ Branch 1 taken 324320 times.
456640 if (rate > max_rate) {
60 max_rate = rate;
61 best_idx = i;
62 }
63 }
64
65 34960 return best_idx;
66 }
67
68 552 size_t FindBestInterval2D(const std::vector<Trial2D> &trials, double m_scaled) {
69 double max_rate = -std::numeric_limits<double>::infinity();
70 size_t best_idx = 0;
71
72
2/2
✓ Branch 0 taken 13800 times.
✓ Branch 1 taken 552 times.
14352 for (size_t i = 0; i + 1 < trials.size(); ++i) {
73 13800 const double dx = trials[i + 1].x - trials[i].x;
74 13800 const double dz = trials[i + 1].z - trials[i].z;
75
76 13800 const double term1 = m_scaled * dx;
77 13800 const double term2 = (dz * dz) / (m_scaled * dx);
78 13800 const double term3 = 2.0 * (trials[i + 1].z + trials[i].z);
79 13800 const double rate = term1 + term2 - term3;
80
81
2/2
✓ Branch 0 taken 3176 times.
✓ Branch 1 taken 10624 times.
13800 if (rate > max_rate) {
82 max_rate = rate;
83 best_idx = i;
84 }
85 }
86
87 552 return best_idx;
88 }
89
90 size_t FindBestZ1D(const std::vector<Trial1D> &trials) {
91 size_t best = 0;
92
2/2
✓ Branch 0 taken 34960 times.
✓ Branch 1 taken 1464 times.
36424 for (size_t i = 1; i < trials.size(); ++i) {
93
2/2
✓ Branch 0 taken 6920 times.
✓ Branch 1 taken 28040 times.
34960 if (trials[i].z < trials[best].z) {
94 best = i;
95 }
96 }
97 return best;
98 }
99
100 size_t FindBestZ2D(const std::vector<Trial2D> &trials) {
101 size_t best = 0;
102
2/2
✓ Branch 0 taken 1416 times.
✓ Branch 1 taken 48 times.
1464 for (size_t i = 1; i < trials.size(); ++i) {
103
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 1152 times.
1416 if (trials[i].z < trials[best].z) {
104 best = i;
105 }
106 }
107 return best;
108 }
109
110 33496 void InsertSorted1D(std::vector<Trial1D> &trials, const Trial1D &value) {
111 size_t pos = 0;
112
3/4
✓ Branch 0 taken 261144 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 227648 times.
✓ Branch 3 taken 33496 times.
261144 while (pos < trials.size() && trials[pos].x < value.x) {
113 227648 ++pos;
114 }
115 33496 trials.insert(trials.begin() + static_cast<std::ptrdiff_t>(pos), value);
116 33496 }
117
118 504 void InsertSorted2D(std::vector<Trial2D> &trials, const Trial2D &value) {
119 size_t pos = 0;
120
3/4
✓ Branch 0 taken 6640 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6136 times.
✓ Branch 3 taken 504 times.
6640 while (pos < trials.size() && trials[pos].x < value.x) {
121 6136 ++pos;
122 }
123
124
2/4
✓ Branch 0 taken 504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 504 times.
✗ Branch 3 not taken.
504 if (pos == trials.size() || std::abs(trials[pos].x - value.x) > 1e-12) {
125 504 trials.insert(trials.begin() + static_cast<std::ptrdiff_t>(pos), value);
126 }
127 504 }
128
129 1464 double Solve1DStrongin(const std::function<double(double)> &func, double a, double b, double eps, int max_iters,
130 double &best_x) {
131 const double r_param = 2.0;
132
133 1464 std::vector<Trial1D> trials;
134
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1464 times.
✓ Branch 3 taken 1464 times.
✗ Branch 4 not taken.
2928 trials.emplace_back(a, func(a));
135
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1464 times.
✓ Branch 3 taken 1464 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1464 times.
2928 trials.emplace_back(b, func(b));
136
137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1464 times.
1464 if (trials[0].x > trials[1].x) {
138 std::swap(trials[0], trials[1]);
139 }
140
141
1/2
✓ Branch 0 taken 34960 times.
✗ Branch 1 not taken.
34960 for (int iter = 0; iter < max_iters; ++iter) {
142 34960 const double m_val = CalculateM(trials);
143
2/2
✓ Branch 0 taken 33936 times.
✓ Branch 1 taken 1024 times.
34960 const double m_scaled = (m_val > 0.0) ? (r_param * m_val) : 1.0;
144
145 34960 const size_t idx = FindBestInterval1D(trials, m_scaled);
146
147
2/2
✓ Branch 0 taken 1464 times.
✓ Branch 1 taken 33496 times.
34960 const double dx = trials[idx + 1].x - trials[idx].x;
148
2/2
✓ Branch 0 taken 1464 times.
✓ Branch 1 taken 33496 times.
34960 if (dx < eps) {
149 break;
150 }
151
152 33496 const double mid = 0.5 * (trials[idx + 1].x + trials[idx].x);
153 33496 const double diff = (trials[idx + 1].z - trials[idx].z) / (2.0 * m_scaled);
154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33496 times.
33496 const double x_new = mid - diff;
155
156
1/4
✓ Branch 1 taken 33496 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
33496 InsertSorted1D(trials, Trial1D(x_new, func(x_new)));
157 }
158
159 const size_t best = FindBestZ1D(trials);
160 1464 best_x = trials[best].x;
161
1/2
✓ Branch 0 taken 1464 times.
✗ Branch 1 not taken.
2928 return trials[best].z;
162 }
163
164 } // namespace
165
166 48 KruglovaA2DMuitSEQ::KruglovaA2DMuitSEQ(const InType &in) {
167 SetTypeOfTask(GetStaticTypeOfTask());
168 48 GetInput() = in;
169 48 }
170
171 48 bool KruglovaA2DMuitSEQ::ValidationImpl() {
172 const auto &in = GetInput();
173
4/8
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 48 times.
48 return in.x_max > in.x_min && in.y_max > in.y_min && in.eps > 0.0 && in.max_iters > 0;
174 }
175
176 48 bool KruglovaA2DMuitSEQ::PreProcessingImpl() {
177 48 GetOutput() = {0.0, 0.0, std::numeric_limits<double>::max()};
178 48 return true;
179 }
180
181 48 bool KruglovaA2DMuitSEQ::RunImpl() {
182 const auto &in = GetInput();
183 const double r_param = 2.0;
184
185 1464 auto compute_z = [&](double x_val, double &best_y) {
186
1/2
✓ Branch 1 taken 1464 times.
✗ Branch 2 not taken.
1464 return Solve1DStrongin([&](double y) { return ObjectiveFunction(x_val, y); }, in.y_min, in.y_max, in.eps,
187
1/2
✓ Branch 0 taken 1464 times.
✗ Branch 1 not taken.
2928 std::max(50, in.max_iters / 10), best_y);
188 48 };
189
190 48 std::vector<Trial2D> x_trials;
191 const int init_points = 20;
192
193
2/2
✓ Branch 0 taken 960 times.
✓ Branch 1 taken 48 times.
1008 for (int i = 0; i < init_points; ++i) {
194 960 const double t = static_cast<double>(i) / static_cast<double>(init_points - 1);
195 960 const double x = in.x_min + ((in.x_max - in.x_min) * t);
196
197 960 double y = 0.0;
198
1/2
✓ Branch 1 taken 960 times.
✗ Branch 2 not taken.
960 double z = compute_z(x, y);
199
1/2
✓ Branch 1 taken 960 times.
✗ Branch 2 not taken.
960 x_trials.emplace_back(x, y, z);
200 }
201
202
2/2
✓ Branch 0 taken 960 times.
✓ Branch 1 taken 48 times.
1008 for (size_t i = 0; i < x_trials.size(); ++i) {
203 size_t min_idx = i;
204
2/2
✓ Branch 0 taken 9120 times.
✓ Branch 1 taken 960 times.
10080 for (size_t j = i + 1; j < x_trials.size(); ++j) {
205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9120 times.
9120 if (x_trials[j].x < x_trials[min_idx].x) {
206 min_idx = j;
207 }
208 }
209 std::swap(x_trials[i], x_trials[min_idx]);
210 }
211
212
1/2
✓ Branch 0 taken 552 times.
✗ Branch 1 not taken.
552 for (int iter = 0; iter < in.max_iters; ++iter) {
213 552 const double m_val = CalculateM(x_trials);
214
1/2
✓ Branch 0 taken 552 times.
✗ Branch 1 not taken.
552 const double m_scaled = (m_val > 0.0) ? (r_param * m_val) : 1.0;
215
216 552 const size_t idx = FindBestInterval2D(x_trials, m_scaled);
217
2/2
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 48 times.
552 const double dx = x_trials[idx + 1].x - x_trials[idx].x;
218
219
2/2
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 48 times.
552 if (dx < in.eps) {
220 break;
221 }
222
223 504 const double mid = 0.5 * (x_trials[idx + 1].x + x_trials[idx].x);
224 504 const double diff = (x_trials[idx + 1].z - x_trials[idx].z) / (2.0 * m_scaled);
225 504 const double x_new = mid - diff;
226
227 504 double y_new = 0.0;
228
1/2
✓ Branch 1 taken 504 times.
✗ Branch 2 not taken.
504 double z_new = compute_z(x_new, y_new);
229
230
1/4
✓ Branch 1 taken 504 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
504 InsertSorted2D(x_trials, Trial2D(x_new, y_new, z_new));
231 }
232
233 const size_t best = FindBestZ2D(x_trials);
234
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 GetOutput() = {x_trials[best].x, x_trials[best].y, x_trials[best].z};
235 48 return true;
236 }
237
238 48 bool KruglovaA2DMuitSEQ::PostProcessingImpl() {
239 48 return true;
240 }
241
242 } // namespace kruglova_a_2d_multistep_par_opt
243