GCC Code Coverage Report


Directory: ./
File: tasks/kiselev_i_trapezoidal_method_for_multidimensional_integrals/stl/src/ops_stl.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 74 75 98.7%
Functions: 8 8 100.0%
Branches: 48 59 81.4%

Line Branch Exec Source
1 #include "kiselev_i_trapezoidal_method_for_multidimensional_integrals/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <functional>
6 #include <future>
7 #include <vector>
8
9 #include "kiselev_i_trapezoidal_method_for_multidimensional_integrals/common/include/common.hpp"
10
11 namespace kiselev_i_trapezoidal_method_for_multidimensional_integrals {
12
13 namespace {
14
15 928 double ComputeChunk(const InType &input_data, const std::vector<int> &steps, int start_index, int end_index) {
16 const double hx =
17 928 static_cast<double>(input_data.right_bounds[0] - input_data.left_bounds[0]) / static_cast<double>(steps[0]);
18
19 const double hy =
20 928 static_cast<double>(input_data.right_bounds[1] - input_data.left_bounds[1]) / static_cast<double>(steps[1]);
21
22 double local_result = 0.0;
23
24
2/2
✓ Branch 0 taken 59272 times.
✓ Branch 1 taken 928 times.
60200 for (int x_index = start_index; x_index < end_index; x_index++) {
25 59272 const double x = input_data.left_bounds[0] + (static_cast<double>(x_index) * hx);
26
27
4/4
✓ Branch 0 taken 59040 times.
✓ Branch 1 taken 232 times.
✓ Branch 2 taken 232 times.
✓ Branch 3 taken 58808 times.
59272 const double weight_x = (x_index == 0 || x_index == steps[0]) ? 0.5 : 1.0;
28
29
2/2
✓ Branch 0 taken 18142312 times.
✓ Branch 1 taken 59272 times.
18201584 for (int y_index = 0; y_index <= steps[1]; y_index++) {
30 18142312 const double y = input_data.left_bounds[1] + (static_cast<double>(y_index) * hy);
31
32
4/4
✓ Branch 0 taken 18083040 times.
✓ Branch 1 taken 59272 times.
✓ Branch 2 taken 59272 times.
✓ Branch 3 taken 18023768 times.
18142312 const double weight_y = (y_index == 0 || y_index == steps[1]) ? 0.5 : 1.0;
33
34 double value = 0.0;
35 18142312 value = KiselevITestTaskSTL::FunctionTypeChoose(input_data.type_function, x, y);
36
37 18142312 local_result += weight_x * weight_y * value;
38 }
39 }
40
41 928 return local_result;
42 }
43
44 } // namespace
45
46
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
144 KiselevITestTaskSTL::KiselevITestTaskSTL(const InType &in) {
47 SetTypeOfTask(GetStaticTypeOfTask());
48
49
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
144 GetInput() = in;
50
51 144 GetOutput() = 0.0;
52 144 }
53
54 144 bool KiselevITestTaskSTL::ValidationImpl() {
55 144 return true;
56 }
57
58 144 bool KiselevITestTaskSTL::PreProcessingImpl() {
59 144 GetOutput() = 0.0;
60
61 144 return true;
62 }
63
64 18142312 double KiselevITestTaskSTL::FunctionTypeChoose(int type_x, double x, double y) {
65
5/5
✓ Branch 0 taken 6643280 times.
✓ Branch 1 taken 1609616 times.
✓ Branch 2 taken 2334424 times.
✓ Branch 3 taken 3223728 times.
✓ Branch 4 taken 4331264 times.
18142312 switch (type_x) {
66 6643280 case 0:
67 6643280 return (x * x) + (y * y);
68
69 1609616 case 1:
70 1609616 return std::sin(x) * std::cos(y);
71
72 2334424 case 2:
73 2334424 return std::sin(x) + std::cos(y);
74
75 3223728 case 3:
76 3223728 return std::exp(x + y);
77
78 4331264 default:
79 4331264 return x + y;
80 }
81 }
82
83 232 double KiselevITestTaskSTL::ComputeIntegral(const std::vector<int> &steps) {
84 const auto &input_data = GetInput();
85
86 232 const int total_iterations = steps[0] + 1;
87
88 int num_threads = 4;
89
90 232 num_threads = std::min(num_threads, total_iterations);
91
92 232 const int chunk_size = total_iterations / num_threads;
93
94 232 const int remainder = total_iterations % num_threads;
95
96 232 std::vector<std::future<double>> futures;
97
98 232 int start_index = 0;
99
100
2/2
✓ Branch 0 taken 928 times.
✓ Branch 1 taken 232 times.
1160 for (int thread_index = 0; thread_index < num_threads; thread_index++) {
101 928 int end_index = start_index + chunk_size;
102
103
2/2
✓ Branch 0 taken 328 times.
✓ Branch 1 taken 600 times.
928 if (thread_index < remainder) {
104 328 end_index++;
105 }
106
107
1/2
✓ Branch 1 taken 928 times.
✗ Branch 2 not taken.
928 futures.emplace_back(
108
1/2
✓ Branch 1 taken 928 times.
✗ Branch 2 not taken.
928 std::async(std::launch::async, ComputeChunk, std::cref(input_data), std::cref(steps), start_index, end_index));
109
110 928 start_index = end_index;
111 }
112
113 const double hx =
114 232 static_cast<double>(input_data.right_bounds[0] - input_data.left_bounds[0]) / static_cast<double>(steps[0]);
115
116 const double hy =
117 232 static_cast<double>(input_data.right_bounds[1] - input_data.left_bounds[1]) / static_cast<double>(steps[1]);
118
119 double result = 0.0;
120
121
2/2
✓ Branch 0 taken 928 times.
✓ Branch 1 taken 232 times.
1160 for (auto &future_result : futures) {
122
1/2
✓ Branch 1 taken 928 times.
✗ Branch 2 not taken.
928 result += future_result.get();
123 }
124
125 232 return result * hx * hy;
126 232 }
127
128
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 8 times.
144 bool KiselevITestTaskSTL::RunImpl() {
129 const auto &input_data = GetInput();
130
131
6/6
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 128 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 120 times.
144 if (input_data.left_bounds.size() != 2 || input_data.right_bounds.size() != 2 || input_data.step_n_size.size() != 2) {
132 24 GetOutput() = 0.0;
133
134 24 return true;
135 }
136
137 120 std::vector<int> steps = input_data.step_n_size;
138
139
2/2
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 120 times.
360 for (const auto &step_value : steps) {
140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240 times.
240 if (step_value <= 0) {
141 GetOutput() = 0.0;
142
143 return true;
144 }
145 }
146
147 120 const double epsilon = input_data.epsilon;
148
149
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 112 times.
120 if (epsilon <= 0.0) {
150
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 GetOutput() = ComputeIntegral(steps);
151
152 8 return true;
153 }
154
155
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 double previous_result = ComputeIntegral(steps);
156
157 double current_result = previous_result;
158
159 const int max_iterations = 1;
160
161
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 for (int iteration_index = 0; iteration_index < max_iterations; iteration_index++) {
162
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 112 times.
336 for (auto &step_value : steps) {
163 224 step_value *= 2;
164 }
165
166
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 current_result = ComputeIntegral(steps);
167
168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (std::abs(current_result - previous_result) < epsilon) {
169 break;
170 }
171
172 previous_result = current_result;
173 }
174
175 112 GetOutput() = current_result;
176
177 112 return true;
178 }
179
180 144 bool KiselevITestTaskSTL::PostProcessingImpl() {
181 144 return true;
182 }
183
184 } // namespace kiselev_i_trapezoidal_method_for_multidimensional_integrals
185