GCC Code Coverage Report


Directory: ./
File: tasks/nikitin_a_monte_carlo/seq/src/ops_seq.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 39 39 100.0%
Functions: 7 7 100.0%
Branches: 27 42 64.3%

Line Branch Exec Source
1 #include "nikitin_a_monte_carlo/seq/include/ops_seq.hpp"
2
3 #include <array>
4 #include <cmath>
5 #include <cstddef>
6 #include <vector>
7
8 #include "nikitin_a_monte_carlo/common/include/common.hpp"
9
10 namespace nikitin_a_monte_carlo {
11
12 namespace {
13 // Вспомогательная функция для вычисления значения тестовой функции
14
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4008800 times.
4008800 double EvaluateFunction(const std::vector<double> &point, FunctionType type) {
15
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4008800 times.
4008800 if (point.empty()) {
16 return 0.0;
17 }
18
19
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) {
20 case FunctionType::kConstant:
21 return 1.0;
22 case FunctionType::kLinear:
23 1200000 return point.at(0);
24 case FunctionType::kProduct:
25
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 400000 times.
400000 if (point.size() < 2) {
26 return 0.0;
27 }
28 400000 return point.at(0) * point.at(1);
29 case FunctionType::kQuadratic:
30
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240000 times.
240000 if (point.size() < 2) {
31 return 0.0;
32 }
33 240000 return (point.at(0) * point.at(0)) + (point.at(1) * point.at(1));
34 case FunctionType::kExponential:
35 160000 return std::exp(point.at(0));
36 default:
37 return 0.0;
38 }
39 }
40
41 // Генерация квазислучайной последовательности Кронекера
42 8897600 double KroneckerSequence(int index, int dimension) {
43 // Используем простые числа для разных измерений
44 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};
45
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)));
46 // Берем дробную часть
47 8897600 alpha = alpha - std::floor(alpha);
48 8897600 return std::fmod(index * alpha, 1.0);
49 }
50 } // namespace
51
52
1/2
✓ Branch 1 taken 176 times.
✗ Branch 2 not taken.
176 NikitinAMonteCarloSEQ::NikitinAMonteCarloSEQ(const InType &in) {
53 SetTypeOfTask(GetStaticTypeOfTask());
54 GetInput() = in;
55 176 GetOutput() = 0.0;
56 176 }
57
58
1/2
✓ Branch 0 taken 176 times.
✗ Branch 1 not taken.
176 bool NikitinAMonteCarloSEQ::ValidationImpl() {
59 const auto &[lower_bounds, upper_bounds, num_points, func_type] = GetInput();
60
61 // Проверка на пустые векторы
62
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()) {
63 return false;
64 }
65
66 // Размерности нижних и верхних границ должны совпадать
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 176 times.
176 if (lower_bounds.size() != upper_bounds.size()) {
68 return false;
69 }
70
71 // Проверка, что нижняя граница меньше верхней для каждого измерения
72
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 176 times.
488 for (std::size_t i = 0; i < lower_bounds.size(); ++i) {
73
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 312 times.
312 if (lower_bounds[i] >= upper_bounds[i]) {
74 return false;
75 }
76 }
77
78 // Количество точек должно быть положительным
79 176 return num_points > 0;
80 }
81
82 176 bool NikitinAMonteCarloSEQ::PreProcessingImpl() {
83 // Предобработка не требуется, так как все данные уже в GetInput()
84 176 return true;
85 }
86
87 176 bool NikitinAMonteCarloSEQ::RunImpl() {
88 const auto &[lower_bounds, upper_bounds, num_points, func_type] = GetInput();
89
90 std::size_t dim = lower_bounds.size();
91
92 // Вычисление объема области интегрирования
93 double volume = 1.0;
94
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 176 times.
488 for (std::size_t i = 0; i < dim; ++i) {
95 312 volume *= (upper_bounds[i] - lower_bounds[i]);
96 }
97
98 // Сумма значений функции в точках
99 double sum = 0.0;
100
101 // Генерация точек и вычисление функции
102
2/2
✓ Branch 0 taken 4008800 times.
✓ Branch 1 taken 176 times.
4008976 for (int i = 0; i < num_points; ++i) {
103 4008800 std::vector<double> point(dim);
104
105 // Генерация точки с помощью последовательности Кронекера
106
2/2
✓ Branch 0 taken 8897600 times.
✓ Branch 1 taken 4008800 times.
12906400 for (std::size_t j = 0; j < dim; ++j) {
107 // Получаем значение в единичном гиперкубе [0,1)
108
1/2
✓ Branch 1 taken 8897600 times.
✗ Branch 2 not taken.
8897600 double u = KroneckerSequence(i, static_cast<int>(j));
109 // Масштабируем в реальную область интегрирования
110 8897600 point[j] = lower_bounds[j] + (u * (upper_bounds[j] - lower_bounds[j]));
111 }
112
113 // Вычисляем значение функции в точке
114
2/4
✓ Branch 1 taken 4008800 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4008800 times.
✗ Branch 4 not taken.
4008800 sum += EvaluateFunction(point, func_type);
115 }
116
117 // Вычисляем приближенное значение интеграла
118 176 double result = volume * sum / static_cast<double>(num_points);
119
120 // Сохраняем результат
121 176 GetOutput() = result;
122
123 176 return true;
124 }
125
126 176 bool NikitinAMonteCarloSEQ::PostProcessingImpl() {
127 // Постобработка не требуется, результат уже сохранен в GetOutput()
128 176 return true;
129 }
130
131 } // namespace nikitin_a_monte_carlo
132