GCC Code Coverage Report


Directory: ./
File: tasks/nikitin_a_monte_carlo/stl/src/ops_stl.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 60 62 96.8%
Functions: 8 8 100.0%
Branches: 36 56 64.3%

Line Branch Exec Source
1 #include "nikitin_a_monte_carlo/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <array>
5 #include <cmath>
6 #include <cstddef>
7 #include <future>
8 #include <thread>
9 #include <tuple>
10 #include <vector>
11
12 #include "nikitin_a_monte_carlo/common/include/common.hpp"
13
14 namespace nikitin_a_monte_carlo {
15
16 namespace {
17 // Вспомогательная функция для вычисления значения тестовой функции
18
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4008800 times.
4008800 double EvaluateFunction(const std::vector<double> &point, FunctionType type) {
19
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4008800 times.
4008800 if (point.empty()) {
20 return 0.0;
21 }
22
23
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1200000 times.
✓ Branch 2 taken 400000 times.
✓ Branch 3 taken 240000 times.
✓ Branch 4 taken 160000 times.
✓ Branch 5 taken 2008800 times.
4008800 switch (type) {
24 case FunctionType::kConstant:
25 return 1.0;
26 case FunctionType::kLinear:
27 1200000 return point.at(0);
28 case FunctionType::kProduct:
29
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 400000 times.
400000 if (point.size() < 2) {
30 return 0.0;
31 }
32 400000 return point.at(0) * point.at(1);
33 case FunctionType::kQuadratic:
34
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240000 times.
240000 if (point.size() < 2) {
35 return 0.0;
36 }
37 240000 return (point.at(0) * point.at(0)) + (point.at(1) * point.at(1));
38 case FunctionType::kExponential:
39 160000 return std::exp(point.at(0));
40 default:
41 return 0.0;
42 }
43 }
44
45 // Генерация квазислучайной последовательности Кронекера
46 8897600 double KroneckerSequence(int index, int dimension) {
47 8897600 const std::array<double, 10> primes = {2.0, 3.0, 5.0, 7.0, 11.0, 13.0, 17.0, 19.0, 23.0, 29.0};
48
1/2
✓ Branch 0 taken 8897600 times.
✗ Branch 1 not taken.
8897600 double alpha = std::sqrt(primes.at(static_cast<std::size_t>(dimension % 10)));
49 8897600 alpha = alpha - std::floor(alpha);
50 8897600 return std::fmod(static_cast<double>(index) * alpha, 1.0);
51 }
52
53 // Функция для вычисления суммы на отрезке [start, end)
54 704 double ComputePartialSum(int start, int end, std::size_t dim, const std::vector<double> &lower_bounds,
55 const std::vector<double> &upper_bounds, FunctionType func_type) {
56 double local_sum = 0.0;
57 704 std::vector<double> point(dim);
58
59
2/2
✓ Branch 0 taken 4008800 times.
✓ Branch 1 taken 704 times.
4009504 for (int i = start; i < end; ++i) {
60
2/2
✓ Branch 0 taken 8897600 times.
✓ Branch 1 taken 4008800 times.
12906400 for (std::size_t j = 0; j < dim; ++j) {
61
1/2
✓ Branch 1 taken 8897600 times.
✗ Branch 2 not taken.
8897600 double u = KroneckerSequence(i, static_cast<int>(j));
62 8897600 point[j] = lower_bounds[j] + (u * (upper_bounds[j] - lower_bounds[j]));
63 }
64
1/2
✓ Branch 1 taken 4008800 times.
✗ Branch 2 not taken.
4008800 local_sum += EvaluateFunction(point, func_type);
65 }
66
67 704 return local_sum;
68 }
69
70 } // namespace
71
72
1/2
✓ Branch 1 taken 176 times.
✗ Branch 2 not taken.
176 NikitinAMonteCarloSTL::NikitinAMonteCarloSTL(const InType &in) {
73 SetTypeOfTask(GetStaticTypeOfTask());
74 GetInput() = in;
75 176 GetOutput() = 0.0;
76 176 }
77
78
1/2
✓ Branch 0 taken 176 times.
✗ Branch 1 not taken.
176 bool NikitinAMonteCarloSTL::ValidationImpl() {
79 const auto &[lower_bounds, upper_bounds, num_points, func_type] = GetInput();
80
81
2/4
✓ Branch 0 taken 176 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 176 times.
176 if (lower_bounds.empty() || upper_bounds.empty()) {
82 return false;
83 }
84
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 176 times.
176 if (lower_bounds.size() != upper_bounds.size()) {
86 return false;
87 }
88
89
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 176 times.
488 for (std::size_t i = 0; i < lower_bounds.size(); ++i) {
90
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 312 times.
312 if (lower_bounds[i] >= upper_bounds[i]) {
91 return false;
92 }
93 }
94
95 176 return num_points > 0;
96 }
97
98 176 bool NikitinAMonteCarloSTL::PreProcessingImpl() {
99 176 return true;
100 }
101
102 176 bool NikitinAMonteCarloSTL::RunImpl() {
103 const auto input = GetInput();
104 const auto &lower_bounds = std::get<0>(input);
105 const auto &upper_bounds = std::get<1>(input);
106 176 const int num_points = std::get<2>(input);
107 176 const FunctionType func_type = std::get<3>(input);
108
109 176 const std::size_t dim = lower_bounds.size();
110
111 double volume = 1.0;
112
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 176 times.
488 for (std::size_t i = 0; i < dim; ++i) {
113 312 volume *= (upper_bounds[i] - lower_bounds[i]);
114 }
115
116 176 unsigned int num_threads = std::thread::hardware_concurrency();
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 176 times.
176 if (num_threads == 0) {
118 num_threads = 2U;
119 }
120
121 // Используем std::min вместо ручного сравнения
122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 176 times.
176 const auto unsigned_num_points = static_cast<unsigned int>(num_points);
123 176 num_threads = std::min(num_threads, unsigned_num_points);
124
125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 176 times.
176 if (num_threads == 0) {
126 num_threads = 1U;
127 }
128
129 176 std::vector<std::future<double>> futures;
130 176 const int points_per_thread = num_points / static_cast<int>(num_threads);
131 176 const int remainder = num_points % static_cast<int>(num_threads);
132
133 int current_start = 0;
134
135
2/2
✓ Branch 0 taken 704 times.
✓ Branch 1 taken 176 times.
880 for (unsigned int thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
136 704 const int start = current_start;
137 704 const int thread_idx_signed = static_cast<int>(thread_idx);
138
1/2
✓ Branch 0 taken 704 times.
✗ Branch 1 not taken.
704 const int end = start + points_per_thread + ((thread_idx_signed < remainder) ? 1 : 0);
139 current_start = end;
140
141 futures.push_back(
142
1/2
✓ Branch 1 taken 704 times.
✗ Branch 2 not taken.
1408 std::async(std::launch::async, ComputePartialSum, start, end, dim, lower_bounds, upper_bounds, func_type));
143 }
144
145 double sum = 0.0;
146
2/2
✓ Branch 0 taken 704 times.
✓ Branch 1 taken 176 times.
880 for (auto &future : futures) {
147
1/2
✓ Branch 1 taken 704 times.
✗ Branch 2 not taken.
704 sum += future.get();
148 }
149
150 176 const double result = volume * sum / static_cast<double>(num_points);
151 176 GetOutput() = result;
152
153 176 return true;
154 176 }
155
156 176 bool NikitinAMonteCarloSTL::PostProcessingImpl() {
157 176 return true;
158 }
159
160 } // namespace nikitin_a_monte_carlo
161