GCC Code Coverage Report


Directory: ./
File: tasks/sizov_d_global_search/seq/src/ops_seq.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 0 104 0.0%
Functions: 0 10 0.0%
Branches: 0 78 0.0%

Line Branch Exec Source
1 #include "sizov_d_global_search/seq/include/ops_seq.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <limits>
7 #include <utility>
8 #include <vector>
9
10 #include "sizov_d_global_search/common/include/common.hpp"
11
12 namespace sizov_d_global_search {
13
14 SizovDGlobalSearchSEQ::SizovDGlobalSearchSEQ(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16 GetInput() = in;
17 GetOutput() = {};
18 }
19
20 bool SizovDGlobalSearchSEQ::ValidationImpl() {
21 const auto &p = GetInput();
22 if (!p.func) {
23 return false;
24 }
25 if (!(p.left < p.right)) {
26 return false;
27 }
28 if (!(p.accuracy > 0.0)) {
29 return false;
30 }
31 if (!(p.reliability > 0.0)) {
32 return false;
33 }
34 if (p.max_iterations <= 0) {
35 return false;
36 }
37 return true;
38 }
39
40 bool SizovDGlobalSearchSEQ::PreProcessingImpl() {
41 const auto &p = GetInput();
42
43 x_.clear();
44 y_.clear();
45
46 x_.reserve(static_cast<std::size_t>(p.max_iterations) + 8U);
47 y_.reserve(static_cast<std::size_t>(p.max_iterations) + 8U);
48
49 const double left = p.left;
50 const double right = p.right;
51
52 const double f_left = p.func(left);
53 const double f_right = p.func(right);
54
55 if (!std::isfinite(f_left) || !std::isfinite(f_right)) {
56 return false;
57 }
58
59 x_.push_back(left);
60 x_.push_back(right);
61 y_.push_back(f_left);
62 y_.push_back(f_right);
63
64 if (f_left <= f_right) {
65 best_x_ = left;
66 best_y_ = f_left;
67 } else {
68 best_x_ = right;
69 best_y_ = f_right;
70 }
71
72 iterations_ = 0;
73 converged_ = false;
74
75 return true;
76 }
77
78 double SizovDGlobalSearchSEQ::EstimateM(double reliability) const {
79 constexpr double kMinSlope = 1e-2;
80
81 const std::size_t n = x_.size();
82 if (n < 2U) {
83 return reliability * kMinSlope;
84 }
85
86 double max_slope = 0.0;
87 for (std::size_t i = 1; i < n; ++i) {
88 const double dx = x_[i] - x_[i - 1U];
89 if (!(dx > 0.0)) {
90 continue;
91 }
92
93 const double y1 = y_[i];
94 const double y2 = y_[i - 1U];
95 if (!std::isfinite(y1) || !std::isfinite(y2)) {
96 continue;
97 }
98
99 const double slope = std::abs(y1 - y2) / dx;
100 if (std::isfinite(slope)) {
101 max_slope = std::max(max_slope, slope);
102 }
103 }
104
105 return reliability * std::max(max_slope, kMinSlope);
106 }
107
108 double SizovDGlobalSearchSEQ::Characteristic(std::size_t idx, double m) const {
109 const double x_right = x_[idx];
110 const double x_left = x_[idx - 1U];
111 const double y_right = y_[idx];
112 const double y_left = y_[idx - 1U];
113
114 const double dx = x_right - x_left;
115 const double df = y_right - y_left;
116
117 return (m * dx) + ((df * df) / (m * dx)) - (2.0 * (y_right + y_left));
118 }
119
120 double SizovDGlobalSearchSEQ::NewPoint(std::size_t idx, double m) const {
121 const double x_right = x_[idx];
122 const double x_left = x_[idx - 1U];
123 const double y_right = y_[idx];
124 const double y_left = y_[idx - 1U];
125
126 const double mid = 0.5 * (x_left + x_right);
127 const double shift = (y_right - y_left) / (2.0 * m);
128
129 double x_new = mid - shift;
130 if (x_new <= x_left || x_new >= x_right) {
131 x_new = mid;
132 }
133 return x_new;
134 }
135
136 std::pair<std::size_t, double> SizovDGlobalSearchSEQ::FindBestInterval(double m) const {
137 double best_char = -std::numeric_limits<double>::infinity();
138 std::size_t best_idx = 1U;
139
140 for (std::size_t i = 1; i < x_.size(); ++i) {
141 const double c = Characteristic(i, m);
142 if (c > best_char) {
143 best_char = c;
144 best_idx = i;
145 }
146 }
147
148 return {best_idx, best_char};
149 }
150
151 std::size_t SizovDGlobalSearchSEQ::InsertSample(double x_new, double y_new) {
152 auto pos = std::ranges::lower_bound(x_, x_new);
153 const std::size_t idx = static_cast<std::size_t>(pos - x_.begin());
154
155 x_.insert(pos, x_new);
156 y_.insert(y_.begin() + static_cast<std::ptrdiff_t>(idx), y_new);
157 return idx;
158 }
159
160 bool SizovDGlobalSearchSEQ::RunImpl() {
161 const auto &p = GetInput();
162
163 if (x_.size() < 2U) {
164 return false;
165 }
166
167 double m = EstimateM(p.reliability);
168
169 for (int iter = 0; iter < p.max_iterations; ++iter) {
170 iterations_ = iter + 1;
171
172 if ((iter % 10) == 0) {
173 m = EstimateM(p.reliability);
174 }
175
176 if (x_.size() < 2U) {
177 converged_ = false;
178 break;
179 }
180
181 const auto [best_idx, _best_char] = FindBestInterval(m);
182 const double left = x_[best_idx - 1U];
183 const double right = x_[best_idx];
184 const double width = right - left;
185
186 if (width <= p.accuracy) {
187 converged_ = true;
188 break;
189 }
190
191 const double x_new = NewPoint(best_idx, m);
192 const double y_new = p.func(x_new);
193 if (!std::isfinite(y_new)) {
194 continue;
195 }
196
197 (void)InsertSample(x_new, y_new);
198
199 if (y_new < best_y_) {
200 best_y_ = y_new;
201 best_x_ = x_new;
202 }
203 }
204
205 GetOutput() = Solution{
206 .argmin = best_x_,
207 .value = best_y_,
208 .iterations = iterations_,
209 .converged = converged_,
210 };
211 return true;
212 }
213
214 bool SizovDGlobalSearchSEQ::PostProcessingImpl() {
215 return true;
216 }
217
218 } // namespace sizov_d_global_search
219