GCC Code Coverage Report


Directory: ./
File: tasks/kondakov_v_global_search/seq/src/ops_seq.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 89 95 93.7%
Functions: 10 11 90.9%
Branches: 43 64 67.2%

Line Branch Exec Source
1 #include "kondakov_v_global_search/seq/include/ops_seq.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <iterator>
7 #include <limits>
8 #include <vector>
9
10 #include "kondakov_v_global_search/common/include/common.hpp"
11
12 namespace kondakov_v_global_search {
13
14 32 KondakovVGlobalSearchSEQ::KondakovVGlobalSearchSEQ(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16 32 GetInput() = in;
17 32 GetOutput() = {};
18 32 }
19
20 4888 double KondakovVGlobalSearchSEQ::EvaluateFunction(double x) {
21 const auto &cfg = GetInput();
22
3/4
✓ Branch 0 taken 4264 times.
✓ Branch 1 taken 464 times.
✓ Branch 2 taken 160 times.
✗ Branch 3 not taken.
4888 switch (cfg.func_type) {
23 4264 case FunctionType::kQuadratic: {
24 4264 double t = cfg.func_param;
25 4264 return (x - t) * (x - t);
26 }
27 464 case FunctionType::kSine:
28 464 return std::sin(x) + (0.1 * x);
29 case FunctionType::kAbs:
30 160 return std::abs(x);
31 default:
32 return std::numeric_limits<double>::quiet_NaN();
33 }
34 }
35
36 32 bool KondakovVGlobalSearchSEQ::ValidationImpl() {
37 const auto &cfg = GetInput();
38
4/8
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 32 times.
32 return cfg.left < cfg.right && cfg.accuracy > 0.0 && cfg.reliability > 0.0 && cfg.max_iterations > 0;
39 }
40
41
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 bool KondakovVGlobalSearchSEQ::PreProcessingImpl() {
42 const auto &cfg = GetInput();
43
44 points_x_.clear();
45 values_y_.clear();
46 32 points_x_.reserve(cfg.max_iterations + 10);
47 32 values_y_.reserve(cfg.max_iterations + 10);
48
49 32 double f_a = EvaluateFunction(cfg.left);
50
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 double f_b = EvaluateFunction(cfg.right);
51
52
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 if (!std::isfinite(f_a) || !std::isfinite(f_b)) {
53 return false;
54 }
55
56 32 points_x_ = {cfg.left, cfg.right};
57 32 values_y_ = {f_a, f_b};
58
59
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 24 times.
32 if (f_a < f_b) {
60 8 best_point_ = cfg.left;
61 8 best_value_ = f_a;
62 } else {
63 24 best_point_ = cfg.right;
64 24 best_value_ = f_b;
65 }
66
67 32 total_evals_ = 0;
68 32 has_converged_ = false;
69 32 return true;
70 }
71
72
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 528 times.
528 double KondakovVGlobalSearchSEQ::ComputeAdaptiveLipschitzEstimate(double r) const {
73 const double min_allowed_slope = 1e-2;
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 528 times.
528 if (points_x_.size() < 2) {
75 return r * min_allowed_slope;
76 }
77
78 double max_local_slope = min_allowed_slope;
79
2/2
✓ Branch 0 taken 60848 times.
✓ Branch 1 taken 528 times.
61376 for (std::size_t i = 1; i < points_x_.size(); ++i) {
80 60848 double dx = points_x_[i] - points_x_[i - 1];
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60848 times.
60848 if (dx <= 0.0) {
82 continue;
83 }
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60848 times.
60848 double dy = std::abs(values_y_[i] - values_y_[i - 1]);
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60848 times.
60848 if (!std::isfinite(dy)) {
86 continue;
87 }
88
1/2
✓ Branch 0 taken 60848 times.
✗ Branch 1 not taken.
60848 double slope = dy / dx;
89
1/2
✓ Branch 0 taken 60848 times.
✗ Branch 1 not taken.
60848 if (std::isfinite(slope) && slope > max_local_slope) {
90 max_local_slope = slope;
91 }
92 }
93 528 return r * max_local_slope;
94 }
95
96 606328 double KondakovVGlobalSearchSEQ::IntervalMerit(std::size_t i, double l_est) const {
97 606328 double x_l = points_x_[i - 1];
98 606328 double x_r = points_x_[i];
99 606328 double f_l = values_y_[i - 1];
100 606328 double f_r = values_y_[i];
101 606328 double h = x_r - x_l;
102 606328 double df = f_r - f_l;
103 606328 return (l_est * h) - (2.0 * (f_l + f_r)) + ((df * df) / (l_est * h));
104 }
105
106 4824 double KondakovVGlobalSearchSEQ::ProposeTrialPoint(std::size_t i, double l_est) const {
107
2/2
✓ Branch 0 taken 4712 times.
✓ Branch 1 taken 112 times.
4824 double x_l = points_x_[i - 1];
108 4824 double x_r = points_x_[i];
109 4824 double f_l = values_y_[i - 1];
110 4824 double f_r = values_y_[i];
111 4824 double mid = 0.5 * (x_l + x_r);
112 4824 double asym = (f_r - f_l) / (2.0 * l_est);
113 4824 double cand = mid - asym;
114
4/4
✓ Branch 0 taken 4712 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 104 times.
✓ Branch 3 taken 4608 times.
4824 if (cand <= x_l || cand >= x_r) {
115 cand = mid;
116 }
117 4824 return cand;
118 }
119
120 std::size_t KondakovVGlobalSearchSEQ::LocateInsertionIndex(double x) const {
121 auto it = std::ranges::lower_bound(points_x_, x);
122 return static_cast<std::size_t>(std::distance(points_x_.begin(), it));
123 }
124
125 4824 void KondakovVGlobalSearchSEQ::InsertEvaluation(double x, double fx) {
126 4824 auto idx = LocateInsertionIndex(x);
127 4824 points_x_.insert(points_x_.begin() + static_cast<std::vector<double>::difference_type>(idx), x);
128 4824 values_y_.insert(values_y_.begin() + static_cast<std::vector<double>::difference_type>(idx), fx);
129
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 4720 times.
4824 if (fx < best_value_) {
130 104 best_value_ = fx;
131 104 best_point_ = x;
132 }
133 4824 }
134
135
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 bool KondakovVGlobalSearchSEQ::RunImpl() {
136 const auto &cfg = GetInput();
137
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (points_x_.size() < 2) {
138 return false;
139 }
140
141 32 double l_est = ComputeAdaptiveLipschitzEstimate(cfg.reliability);
142
143
1/2
✓ Branch 0 taken 4856 times.
✗ Branch 1 not taken.
4856 for (int step = 0; step < cfg.max_iterations; ++step) {
144
2/2
✓ Branch 0 taken 496 times.
✓ Branch 1 taken 4360 times.
4856 if (step % 10 == 0) {
145 496 l_est = ComputeAdaptiveLipschitzEstimate(cfg.reliability);
146 }
147
148 std::size_t best_i = 1;
149 double max_merit = -std::numeric_limits<double>::infinity();
150
2/2
✓ Branch 0 taken 606328 times.
✓ Branch 1 taken 4856 times.
611184 for (std::size_t i = 1; i < points_x_.size(); ++i) {
151 606328 double m = IntervalMerit(i, l_est);
152
2/2
✓ Branch 0 taken 62248 times.
✓ Branch 1 taken 544080 times.
606328 if (m > max_merit) {
153 max_merit = m;
154 best_i = i;
155 }
156 }
157
158 4856 double width = points_x_[best_i] - points_x_[best_i - 1];
159
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 4824 times.
4856 if (width <= cfg.accuracy) {
160 32 has_converged_ = true;
161 32 break;
162 }
163
164 4824 double x = ProposeTrialPoint(best_i, l_est);
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4824 times.
4824 double fx = EvaluateFunction(x);
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4824 times.
4824 if (!std::isfinite(fx)) {
167 continue;
168 }
169
170 4824 InsertEvaluation(x, fx);
171 4824 total_evals_++;
172 }
173
174 32 GetOutput() =
175 32 Solution{.argmin = best_point_, .value = best_value_, .iterations = total_evals_, .converged = has_converged_};
176 32 return true;
177 }
178
179 32 bool KondakovVGlobalSearchSEQ::PostProcessingImpl() {
180 32 return true;
181 }
182
183 } // namespace kondakov_v_global_search
184