GCC Code Coverage Report


Directory: ./
File: tasks/nikitin_a_monte_carlo/omp/src/ops_omp.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 36 36 100.0%
Functions: 7 7 100.0%
Branches: 20 32 62.5%

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