GCC Code Coverage Report


Directory: ./
File: Tools/table_interpolation.cpp
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 58 114 50.9%
Branches: 34 166 20.5%

Line Branch Exec Source
1 // ______ ______ _ _ _____ ______
2 // | ____| ____| | (_)/ ____| | ____|
3 // | |__ | |__ | | _| (___ ___| |__
4 // | __| | __| | | | |\___ \ / __| __|
5 // | | | |____| |____| |____) | (__| |____
6 // |_| |______|______|_|_____/ \___|______|
7 // Finite Elements for Life Sciences and Engineering
8 //
9 // License: LGL2.1 License
10 // FELiScE default license: LICENSE in root folder
11 //
12 // Main authors: Vicente Mataix Ferrandiz
13 //
14
15 // System includes
16 #include <iomanip>
17
18 // External includes
19 #include <tabulate/single_include/tabulate/tabulate.hpp>
20
21 // Project includes
22 #include "Tools/table_interpolation.hpp"
23
24 namespace felisce
25 {
26 1324 double TableInterpolation::GetValue(const double X) const
27 {
28 1324 const std::size_t size = mData.size();
29
30
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1324 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1324 if(size == 0) std::cout << "Get value from empty table" << std::endl;
31
32
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1324 times.
1324 if(size == 1) { // Constant table. Returning the only value we have.
33 return mData.begin()->second[0];
34 }
35
36 double result;
37
2/2
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 1300 times.
1324 if(X <= mData[0].first) {
38
1/2
✓ Branch 7 taken 24 times.
✗ Branch 8 not taken.
24 return Interpolate(X, mData[0].first, mData[0].second[0], mData[1].first, mData[1].second[0], result);
39 }
40
41
2/2
✓ Branch 0 taken 27936 times.
✓ Branch 1 taken 20 times.
27956 for(std::size_t i = 1 ; i < size ; i++) {
42
2/2
✓ Branch 1 taken 1280 times.
✓ Branch 2 taken 26656 times.
27936 if(X <= mData[i].first) {
43
1/2
✓ Branch 7 taken 1280 times.
✗ Branch 8 not taken.
1280 return Interpolate(X, mData[i-1].first, mData[i-1].second[0], mData[i].first, mData[i].second[0], result);
44 }
45 }
46
47 // Now the x is outside the table and we hae to extrapolate it using last two records of table.
48
1/2
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
20 return Interpolate(X, mData[size-2].first, mData[size-2].second[0], mData[size-1].first, mData[size-1].second[0], result);
49 }
50
51 /***********************************************************************************/
52 /***********************************************************************************/
53
54 2 TableInterpolation::result_row_type& TableInterpolation::GetNearestRow(const double X)
55 {
56 2 const std::size_t size = mData.size();
57
58
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(size == 0) std::cout << "Get value from empty table" << std::endl;
59
60
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(size == 1) { // Constant table. Returning the only value we have.
61 return mData.begin()->second;
62 }
63
64
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if(X <= mData[0].first) {
65 return mData[0].second;
66 }
67
68
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 for(std::size_t i = 1 ; i < size ; i++) {
69
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3 times.
5 if(X <= mData[i].first) {
70
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 return ((X - mData[i-1].first) < (mData[i].first - X)) ? mData[i-1].second : mData[i].second;
71 }
72 }
73
74 // Now the x is outside the table and we hae to extrapolate it using last two records of table.
75 return mData[size-1].second;
76 }
77
78 /***********************************************************************************/
79 /***********************************************************************************/
80
81 const double& TableInterpolation::GetNearestValue(const double X) const
82 {
83 const std::size_t size = mData.size();
84
85 if(size == 0) std::cout << "Get value from empty table" << std::endl;
86
87 if(size == 1) { // Constant table. Returning the only value we have.
88 return mData.begin()->second[0];
89 }
90
91 if(X <= mData[0].first) {
92 return mData[0].second[0];
93 }
94
95 for(std::size_t i = 1 ; i < size ; i++) {
96 if(X <= mData[i].first) {
97 return ((X - mData[i-1].first) < (mData[i].first - X)) ? mData[i-1].second[0] : mData[i].second[0];
98 }
99 }
100
101 // Now the x is outside the table and we have to extrapolate it using last two records of table.
102 return mData[size-1].second[0];
103 }
104
105 /***********************************************************************************/
106 /***********************************************************************************/
107
108 double& TableInterpolation::GetNearestValue(const double X)
109 {
110 const std::size_t size = mData.size();
111
112 if(size == 0) std::cout << "Get value from empty table" << std::endl;
113
114 if(size == 1) { // Constant table. Returning the only value we have.
115 return mData.begin()->second[0];
116 }
117
118 if(X <= mData[0].first) {
119 return mData[0].second[0];
120 }
121
122 for(std::size_t i = 1 ; i < size ; i++) {
123 if(X <= mData[i].first) {
124 return ((X - mData[i-1].first) < (mData[i].first - X)) ? mData[i-1].second[0] : mData[i].second[0];
125 }
126 }
127
128 // Now the x is outside the table and we have to extrapolate it using last two records of table.
129 return mData[size-1].second[0];
130 }
131
132 /***********************************************************************************/
133 /***********************************************************************************/
134
135 1324 double& TableInterpolation::Interpolate(const double X, const double X1, const double Y1, const double X2, const double Y2, double& Result) const
136 {
137 1324 const double epsilon = 1e-12;
138
139 1324 const double dx = X2 - X1;
140 1324 const double dy = Y2 - Y1;
141
142 1324 double scale = 0.0;
143
144
1/2
✓ Branch 0 taken 1324 times.
✗ Branch 1 not taken.
1324 if (dx > epsilon) {
145 1324 scale = (X - X1) / dx;
146 }
147
148 1324 Result = Y1 + dy * scale;
149
150 1324 return Result;
151 }
152
153 /***********************************************************************************/
154 /***********************************************************************************/
155
156 6 void TableInterpolation::insert(const double X, const double Y)
157 {
158 6 const result_row_type a = {{Y}};
159
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 insert(X,a);
160 6 }
161
162 /***********************************************************************************/
163 /***********************************************************************************/
164
165 6 void TableInterpolation::insert(const double X, const result_row_type& Y)
166 {
167 6 const std::size_t size = mData.size();
168
169
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if(size == 0) {
170
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 mData.push_back(RecordType(X,Y));
171
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 } else if(X <= mData[0].first) {
172
1/2
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 mData.insert(mData.begin(), RecordType(X,Y));
173 } else if(X > mData.back().first) {
174 mData.push_back(RecordType(X,Y));
175 } else {
176 for(std::size_t i = 1 ; i < size ; i++) {
177 if((X > mData[i-1].first) && (X <= mData[i].first)) {
178 mData.insert(mData.begin() + i, RecordType(X,Y));
179 break;
180 }
181 }
182 }
183 6 }
184
185 /***********************************************************************************/
186 /***********************************************************************************/
187
188 622 void TableInterpolation::PushBack(const double X, const double Y)
189 {
190 622 const result_row_type a = {{Y}};
191
1/2
✓ Branch 2 taken 622 times.
✗ Branch 3 not taken.
622 mData.push_back(RecordType(X,a));
192 622 }
193
194 /***********************************************************************************/
195 /***********************************************************************************/
196
197 4 double TableInterpolation::GetDerivative(const double X) const
198 {
199 4 const std::size_t size = mData.size();
200
201
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
4 if(size == 0) std::cout << "Get value from empty table" << std::endl;
202
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(size == 1) { // Constant table. Returning the only value we have.
204 return 0.0;
205 }
206
207 4 double result = 0.0;
208
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if(X <= mData[0].first) {
209 //return Interpolate(X, mData[0].first, mData[0].second[0], mData[1].first, mData[1].second[0], result);
210 return 0.0;
211 }
212
213
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 for(std::size_t i = 1 ; i < size ; i++) {
214
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 6 times.
10 if(X <= mData[i].first) {
215
1/2
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
4 return InterpolateDerivative( mData[i-1].first, mData[i-1].second[0], mData[i].first, mData[i].second[0], result);
216 }
217 }
218
219 // If it lies outside the table values we will return 0.0.
220 return 0.0;
221 }
222
223 /***********************************************************************************/
224 /***********************************************************************************/
225
226 4 double& TableInterpolation::InterpolateDerivative( const double X1, const double Y1, const double X2, const double Y2, double& Result) const
227 {
228 4 const double epsilon = 1e-12;
229 4 double dx = X2 - X1;
230 4 const double dy = Y2 - Y1;
231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (dx < epsilon) {
232 dx=epsilon;
233 std::cout
234 << "*******************************************\n"
235 << "*** ATTENTION: SMALL dX WHEN COMPUTING ***\n"
236 << "*** DERIVATIVE FROM TABLE. SET TO 1E-12 ***\n"
237 << "*******************************************"
238 <<std::endl;
239 }
240 4 Result= dy/dx;
241 4 return Result;
242 }
243
244 /***********************************************************************************/
245 /***********************************************************************************/
246
247 void TableInterpolation::PrintData(std::ostream& rOStream) const
248 {
249 tabulate::Table table;
250 table.add_row({"X", "Y"});
251 const auto& r_data = Data();
252 const std::size_t size = r_data.size();
253 for(std::size_t i = 0 ; i < size ; i++) {
254 std::stringstream buffer1, buffer2;
255 buffer1 << std::setprecision(16) << std::scientific << r_data[i].first;
256 buffer2 << std::setprecision(16) << std::scientific << r_data[i].second[0];
257 table.add_row({buffer1.str(), buffer2.str()});
258 }
259
260 // Center align X, Y
261 table.column(0).format().font_align(tabulate::FontAlign::center);
262 table.column(1).format().font_align(tabulate::FontAlign::center);
263
264 // Center-align and color header cells
265 for (std::size_t i = 0; i < 2; ++i) {
266 table[0][i].format()
267 .font_color(tabulate::Color::yellow)
268 .font_align(tabulate::FontAlign::center)
269 .font_style({tabulate::FontStyle::bold});
270 }
271
272 rOStream << table << std::endl;
273 }
274
275 };
276
277