GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 85.3% 180 / 0 / 211
Functions: 90.0% 9 / 0 / 10
Branches: 64.0% 151 / 0 / 236

other/s_common.F90
Line Branch Exec Source
1 submodule(m_common) s_common
2 contains
3 !> @brief Sort an array of integers using the quicksort algorithm
4 !>
5 !> @param [inout] array The array of integers to be sorted
6 !> @param [in] _(optional) inverse If true, sort in descending order; otherwise, ascending order (default: false)
7
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1006 times.
1006 module pure subroutine sort_int(array, inverse)
8 implicit none
9
10 integer, intent(inout) :: array(:)
11 logical, intent(in), optional :: inverse
12
13 1006 call quicksort_int(array, 1, size(array))
14
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 1006 times.
1006 if (present(inverse)) then
15 if (inverse) then
16 array = array(size(array):1:-1)
17 end if
18 end if
19
20 contains
21
22
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1894 times.
1894 pure recursive subroutine quicksort_int(a, left, right)
23 integer, intent(inout) :: a(:)
24 integer, intent(in) :: left, right
25 integer :: i, j, pivot_idx, pivot, temp
26
27
1/2
✓ Branch 4 → 5 taken 1894 times.
✗ Branch 4 → 23 not taken.
1894 if (left < right) then
28 1894 pivot_idx = left + (right - left) / 2
29 1894 pivot = a(pivot_idx)
30 1894 i = left
31 1894 j = right
32 do
33
2/2
✓ Branch 7 → 8 taken 1920 times.
✓ Branch 7 → 10 taken 171 times.
2091 do while (a(i) < pivot)
34 2091 i = i + 1
35 end do
36
2/2
✓ Branch 11 → 12 taken 1826 times.
✓ Branch 11 → 13 taken 1920 times.
3746 do while (a(j) > pivot)
37 1826 j = j - 1
38 end do
39
2/2
✓ Branch 14 → 15 taken 1915 times.
✓ Branch 14 → 16 taken 5 times.
1920 if (i <= j) then
40 temp = a(i)
41 1915 a(i) = a(j)
42 1915 a(j) = temp
43 1915 i = i + 1
44 1915 j = j - 1
45 end if
46
2/2
✓ Branch 16 → 6 taken 26 times.
✓ Branch 16 → 17 taken 1894 times.
1920 if (i > j) exit
47 end do
48
2/2
✓ Branch 17 → 18 taken 43 times.
✓ Branch 17 → 20 taken 1851 times.
1894 if (left < j) call quicksort_int(a, left, j)
49
2/2
✓ Branch 20 → 21 taken 845 times.
✓ Branch 20 → 23 taken 1049 times.
1894 if (i < right) call quicksort_int(a, i, right)
50 end if
51 1894 end subroutine quicksort_int
52
53 end subroutine sort_int
54
55 !> @brief Sort an array of real numbers using the quicksort algorithm
56 !>
57 !> @param [inout] array The array of real numbers to be sorted
58 !> @param [in] _(optional) inverse If true, sort in descending order; otherwise, ascending order (default: false)
59 !> @param [in] _(optional) sort_fun A function to determine the sorting order
60
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 6 times.
6 module subroutine sort_real(array, inverse, sort_fun)
61 implicit none
62
63 real(wp), intent(inout) :: array(:)
64 logical, intent(in), optional :: inverse
65 procedure(user_function_1d_interface), optional :: sort_fun
66
67 6 call quicksort_real(array, 1, size(array))
68
2/2
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 16 taken 5 times.
6 if (present(inverse)) then
69
1/2
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 16 not taken.
1 if (inverse) then
70
5/6
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 9 not taken.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 12 taken 10 times.
✓ Branch 13 → 14 taken 10 times.
✓ Branch 13 → 15 taken 1 time.
22 array = array(size(array):1:-1)
71 end if
72 end if
73
74 contains
75
76
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1155 times.
1155 recursive subroutine quicksort_real(a, left, right)
77 real(wp), intent(inout) :: a(:)
78 integer, intent(in) :: left, right
79 integer :: i, j, pivot_idx
80 real(wp) :: pivot, temp
81 real(wp) :: val_i, val_j
82
83
1/2
✓ Branch 4 → 5 taken 1155 times.
✗ Branch 4 → 36 not taken.
1155 if (left < right) then
84 1155 pivot_idx = left + (right - left) / 2
85
2/2
✓ Branch 5 → 6 taken 387 times.
✓ Branch 5 → 7 taken 768 times.
1155 if (present(sort_fun)) then
86 387 pivot = sort_fun(a(pivot_idx))
87 else
88 768 pivot = a(pivot_idx)
89 end if
90 1155 i = left
91 1155 j = right
92 do
93
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 7088 times.
7088 do while (i <= right)
94
2/2
✓ Branch 12 → 13 taken 2403 times.
✓ Branch 12 → 14 taken 4685 times.
7088 if (present(sort_fun)) then
95 2403 val_i = sort_fun(a(i))
96 else
97 4685 val_i = a(i)
98 end if
99
2/2
✓ Branch 15 → 16 taken 3246 times.
✓ Branch 15 → 18 taken 3842 times.
7088 if (val_i >= pivot) exit
100 7088 i = i + 1
101 end do
102
1/2
✓ Branch 19 → 20 taken 7439 times.
✗ Branch 19 → 26 not taken.
7439 do while (j >= left)
103
2/2
✓ Branch 20 → 21 taken 2522 times.
✓ Branch 20 → 22 taken 4917 times.
7439 if (present(sort_fun)) then
104 2522 val_j = sort_fun(a(j))
105 else
106 4917 val_j = a(j)
107 end if
108
2/2
✓ Branch 23 → 24 taken 3246 times.
✓ Branch 23 → 25 taken 4193 times.
7439 if (val_j <= pivot) exit
109 7439 j = j - 1
110 end do
111
2/2
✓ Branch 27 → 28 taken 2980 times.
✓ Branch 27 → 29 taken 266 times.
3246 if (i <= j) then
112 2980 temp = a(i)
113 2980 a(i) = a(j)
114 2980 a(j) = temp
115 2980 i = i + 1
116 2980 j = j - 1
117 end if
118
2/2
✓ Branch 29 → 9 taken 2091 times.
✓ Branch 29 → 30 taken 1155 times.
3246 if (i > j) exit
119 end do
120
2/2
✓ Branch 30 → 31 taken 576 times.
✓ Branch 30 → 33 taken 579 times.
1155 if (left < j) call quicksort_real(a, left, j)
121
2/2
✓ Branch 33 → 34 taken 573 times.
✓ Branch 33 → 36 taken 582 times.
1155 if (i < right) call quicksort_real(a, i, right)
122 end if
123 1155 end subroutine quicksort_real
124
125 end subroutine sort_real
126
127 !> @brief Compute a sort permutation of an array of real numbers (descending, high to low)
128 !>
129 !> @param [in] array The array of real numbers to rank
130 !> @param [out] perm The permutation indices such that array(perm) is sorted descending
131 !> @param [in] sort_fun _(optional)_ Applied to each element before comparison
132 module subroutine sort_perm(array, perm, sort_fun)
133 implicit none
134
135 real(wp), intent(in) :: array(:)
136 integer, intent(out) :: perm(:)
137 procedure(user_function_1d_interface), optional :: sort_fun
138
139 integer :: i, j, tmp
140 real(wp) :: key_i, key_j
141
142 do i = 1, size(perm)
143 perm(i) = i
144 end do
145
146 ! Insertion sort on perm, keyed by array values descending
147 do i = 2, size(perm)
148 tmp = perm(i)
149 if (present(sort_fun)) then
150 key_i = sort_fun(array(tmp))
151 else
152 key_i = array(tmp)
153 end if
154 j = i - 1
155 do while (j >= 1)
156 if (present(sort_fun)) then
157 key_j = sort_fun(array(perm(j)))
158 else
159 key_j = array(perm(j))
160 end if
161 if (key_j >= key_i) exit
162 perm(j + 1) = perm(j)
163 j = j - 1
164 end do
165 perm(j + 1) = tmp
166 end do
167 end subroutine sort_perm
168
169 !> @brief Compute the union of two sets of integers
170 !>
171 !> @param [out] union The resulting union of the two sets
172 !> @param [in] set1 The first set of integers
173 !> @param [in] set2 The second set of integers
174
2/4
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 1 time.
1 module subroutine set_union(union, set1, set2)
175 implicit none
176
177 integer, allocatable, intent(out) :: union(:)
178 integer, intent(in) :: set1(0:), set2(0:)
179
180 1 integer, allocatable :: temp(:)
181 integer :: nr_duplicates, i
182
183 ! 1: append, 2: sort, 3: remove duplicates
184
185
1/4
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 13 taken 1 time.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 13 not taken.
1 if (size(set1) == 0 .and. size(set2) == 0) then
186 allocate (union(0:-1))
187 return
188 end if
189
190
6/12
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 1 time.
✓ Branch 15 → 14 taken 1 time.
✗ Branch 15 → 16 not taken.
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 18 not taken.
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 20 not taken.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 22 taken 1 time.
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 24 taken 1 time.
3 allocate (temp(0:size(set1) + size(set2) - 1))
191
2/2
✓ Branch 25 → 26 taken 6 times.
✓ Branch 25 → 27 taken 1 time.
7 temp(0:size(set1) - 1) = set1
192
2/2
✓ Branch 28 → 29 taken 6 times.
✓ Branch 28 → 30 taken 1 time.
7 temp(size(set1):size(set1) + size(set2) - 1) = set2
193
194 1 call sort(temp)
195
196 nr_duplicates = 0
197
2/2
✓ Branch 33 → 34 taken 11 times.
✓ Branch 33 → 36 taken 1 time.
12 do i = 0, size(temp) - 2
198
2/2
✓ Branch 34 → 32 taken 8 times.
✓ Branch 34 → 35 taken 3 times.
12 if (temp(i) == temp(i + 1)) then
199 3 nr_duplicates = nr_duplicates + 1
200 end if
201 end do
202
203
7/14
✗ Branch 37 → 38 not taken.
✓ Branch 37 → 39 taken 1 time.
✓ Branch 39 → 38 taken 1 time.
✗ Branch 39 → 40 not taken.
✓ Branch 40 → 41 taken 1 time.
✗ Branch 40 → 42 not taken.
✓ Branch 42 → 43 taken 1 time.
✗ Branch 42 → 44 not taken.
✗ Branch 44 → 45 not taken.
✓ Branch 44 → 46 taken 1 time.
✗ Branch 46 → 47 not taken.
✓ Branch 46 → 48 taken 1 time.
✗ Branch 48 → 49 not taken.
✓ Branch 48 → 50 taken 1 time.
3 allocate (union(0:size(temp) - nr_duplicates - 1))
204
205 nr_duplicates = 0
206 1 union(0) = temp(0)
207
2/2
✓ Branch 51 → 52 taken 11 times.
✓ Branch 51 → 56 taken 1 time.
12 do i = 1, size(temp) - 1
208
2/2
✓ Branch 52 → 53 taken 3 times.
✓ Branch 52 → 54 taken 8 times.
12 if (temp(i - 1) == temp(i)) then
209 3 nr_duplicates = nr_duplicates + 1
210 else
211 8 union(i - nr_duplicates) = temp(i)
212 end if
213 end do
214
215 1 deallocate (temp)
216 end subroutine set_union
217
218 11 module pure subroutine prime_factors(n, factors)
219 implicit none
220
221 integer, intent(in) :: n
222 integer, allocatable, intent(out) :: factors(:)
223
224 integer :: num, divisor, count, i
225
226 ! Handle edge cases
227
2/2
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 8 taken 9 times.
11 if (n <= 1) then
228
2/4
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 2 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 2 times.
2 allocate (factors(0))
229 2 return
230 end if
231
232 ! Count the number of prime factors
233 num = n
234 count = 0
235
236 ! Count factors of 2
237
2/2
✓ Branch 8 → 9 taken 16 times.
✓ Branch 8 → 10 taken 9 times.
25 do while (mod(num, 2) == 0)
238 16 count = count + 1
239 16 num = num / 2
240 end do
241
242 ! Count odd factors
243 divisor = 3
244
2/2
✓ Branch 11 → 12 taken 8 times.
✓ Branch 11 → 16 taken 9 times.
17 do while (divisor * divisor <= num)
245
2/2
✓ Branch 12 → 13 taken 5 times.
✓ Branch 12 → 14 taken 8 times.
13 do while (mod(num, divisor) == 0)
246 5 count = count + 1
247 5 num = num / divisor
248 end do
249 8 divisor = divisor + 2
250 end do
251
252 ! If num > 1, then it's a prime factor
253
2/2
✓ Branch 17 → 18 taken 5 times.
✓ Branch 17 → 19 taken 4 times.
9 if (num > 1) then
254 5 count = count + 1
255 end if
256
257 ! Allocate the array
258
7/14
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 9 times.
✓ Branch 21 → 20 taken 9 times.
✗ Branch 21 → 22 not taken.
✓ Branch 22 → 23 taken 9 times.
✗ Branch 22 → 24 not taken.
✓ Branch 24 → 25 taken 9 times.
✗ Branch 24 → 26 not taken.
✗ Branch 26 → 27 not taken.
✓ Branch 26 → 28 taken 9 times.
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 9 times.
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 32 taken 9 times.
27 allocate (factors(count))
259
260 ! Fill the array with prime factors
261 num = n
262 i = 1
263
264 ! Extract factors of 2
265
2/2
✓ Branch 33 → 34 taken 16 times.
✓ Branch 33 → 35 taken 9 times.
25 do while (mod(num, 2) == 0)
266 16 factors(i) = 2
267 16 i = i + 1
268 16 num = num / 2
269 end do
270
271 ! Extract odd factors
272 divisor = 3
273
2/2
✓ Branch 36 → 37 taken 8 times.
✓ Branch 36 → 41 taken 9 times.
17 do while (divisor * divisor <= num)
274
2/2
✓ Branch 37 → 38 taken 5 times.
✓ Branch 37 → 39 taken 8 times.
13 do while (mod(num, divisor) == 0)
275 5 factors(i) = divisor
276 5 i = i + 1
277 5 num = num / divisor
278 end do
279 8 divisor = divisor + 2
280 end do
281
282 ! If num > 1, then it's a prime factor
283
2/2
✓ Branch 42 → 43 taken 5 times.
✓ Branch 42 → 44 taken 4 times.
9 if (num > 1) then
284 5 factors(i) = num
285 end if
286
287 end subroutine prime_factors
288
289 !> @brief Split an integer into two factors that are as close as possible
290 !>
291 !> Given an integer N, find n1 and n2 such that N = n1 * n2 and |n1 - n2| is minimized.
292 !> The result satisfies n1 <= n2.
293 !>
294 !> @param[in] n The integer to split
295 !> @param[out] n1 The smaller factor
296 !> @param[out] n2 The larger factor
297 3835 module pure subroutine balanced_split_2(n, n1, n2)
298 implicit none
299
300 integer, intent(in) :: n
301 integer, intent(out) :: n1, n2
302
303 integer :: i, sqrt_n
304
305 ! Handle edge cases
306
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 3835 times.
3835 if (n <= 0) then
307 n1 = 1
308 n2 = n
309 return
310 end if
311
312
2/2
✓ Branch 4 → 5 taken 3 times.
✓ Branch 4 → 6 taken 3832 times.
3835 if (n == 1) then
313 3 n1 = 1
314 3 n2 = 1
315 3 return
316 end if
317
318 ! Start from sqrt(n) and work downward to find the largest divisor <= sqrt(n)
319 3832 sqrt_n = int(sqrt(real(n)))
320
321
1/2
✓ Branch 7 → 8 taken 35439 times.
✗ Branch 7 → 11 not taken.
35439 do i = sqrt_n, 1, -1
322
2/2
✓ Branch 8 → 9 taken 3832 times.
✓ Branch 8 → 10 taken 31607 times.
35439 if (mod(n, i) == 0) then
323 3832 n1 = i
324 3832 n2 = n / i
325 3832 return
326 end if
327 end do
328
329 ! Should never reach here, but as a fallback
330 n1 = 1
331 n2 = n
332
333 end subroutine balanced_split_2
334
335 !> @brief Split an integer into three factors that are as close as possible
336 !>
337 !> Given an integer N, find n1, n2, and n3 such that N = n1 * n2 * n3 and the factors are as balanced as possible.
338 !> The result satisfies n1 <= n2 <= n3.
339 !>
340 !> @param[in] n The integer to split
341 !> @param[out] n1 The smallest factor
342 !> @param[out] n2 The middle factor
343 !> @param[out] n3 The largest factor
344 1006 module pure subroutine balanced_split_3(n, n1, n2, n3)
345 implicit none
346
347 integer, intent(in) :: n
348 integer, intent(out) :: n1, n2, n3
349
350 integer :: i, cbrt_n, temp_n2, temp_n3
351 integer :: best_n1, best_n2, best_n3
352 integer :: max_diff, current_max_diff
353
354 integer :: nlist(3)
355
356 ! Handle edge cases
357
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1006 times.
1006 if (n <= 0) then
358 n1 = 1
359 n2 = 1
360 n3 = n
361 2 return
362 end if
363
364
2/2
✓ Branch 4 → 5 taken 2 times.
✓ Branch 4 → 6 taken 1004 times.
1006 if (n == 1) then
365 2 n1 = 1
366 2 n2 = 1
367 2 n3 = 1
368 2 return
369 end if
370
371 ! Start from cbrt(n) and search for the most balanced factorization
372 1004 cbrt_n = int(real(n)**(1.0 / 3.0)) + 1
373 best_n1 = 1
374 best_n2 = 1
375 best_n3 = n
376 1004 max_diff = n - 1
377
378
2/2
✓ Branch 7 → 8 taken 8000 times.
✓ Branch 7 → 13 taken 1004 times.
9004 do i = cbrt_n, 1, -1
379
2/2
✓ Branch 8 → 9 taken 5299 times.
✓ Branch 8 → 10 taken 2701 times.
9004 if (mod(n, i) == 0) then
380 ! i is a divisor, now split n/i into two balanced factors
381 2701 call balanced_split(n / i, temp_n2, temp_n3)
382
383 ! Check if this is more balanced
384 2701 current_max_diff = max(temp_n3 - i, temp_n3 - temp_n2, temp_n2 - i)
385
386
2/2
✓ Branch 11 → 9 taken 1693 times.
✓ Branch 11 → 12 taken 1008 times.
2701 if (current_max_diff < max_diff) then
387 best_n1 = i
388 best_n2 = temp_n2
389 best_n3 = temp_n3
390 max_diff = current_max_diff
391 end if
392 end if
393 end do
394
395 ! Sort the results to ensure n1 <= n2 <= n3
396
2/2
✓ Branch 15 → 16 taken 3012 times.
✓ Branch 15 → 17 taken 1004 times.
4016 nlist = [best_n1, best_n2, best_n3]
397 1004 call sort_int(nlist)
398 1004 n1 = nlist(1)
399 1004 n2 = nlist(2)
400 1004 n3 = nlist(3)
401
402 end subroutine balanced_split_3
403
404 91 module real(wp) function brent(fun, xa_in, xb_in, x_tol, max_iter, fa_in, fb_in, success) result(xsol)
405 implicit none
406
407 procedure(user_function_1d_interface) :: fun
408 real(wp), intent(in) :: xa_in, xb_in, x_tol
409 integer, intent(in) :: max_iter
410 real(wp), intent(in), optional :: fa_in, fb_in
411 logical, intent(out), optional :: success
412
413 ! Local variables
414 real(wp) :: xa, xb, fa, fb, fc, xc, xd, xe, xm, p, q, r, s
415 real(wp) :: toler
416 integer :: iter, flag
417
418
419
420 iter = 0
421
422 91 xa = xa_in
423 91 xb = xb_in
424
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 91 times.
91 if (present(fa_in)) then
425 fa = fa_in
426 else
427 91 fa = fun(xa)
428 iter = iter + 1
429 endif
430
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 91 times.
91 if (present(fb_in)) then
431 fb = fb_in
432 else
433 91 fb = fun(xb)
434 91 iter = iter + 1
435 endif
436
437 flag = 1 ! 1: continue, 0: converged, -1: some problem
438
1/2
✓ Branch 9 → 10 taken 91 times.
✗ Branch 9 → 13 not taken.
91 if (fa == 0) then
439 xsol = xa
440 flag = 0
441
1/2
✓ Branch 10 → 11 taken 91 times.
✗ Branch 10 → 13 not taken.
91 elseif (fb == 0) then
442 xsol = xb
443 flag = 0
444
2/2
✓ Branch 11 → 12 taken 21 times.
✓ Branch 11 → 13 taken 70 times.
91 elseif (fa * fb > 0) then
445 xsol = 0
446 flag = -1
447 endif
448
449 xc = xa; fc = fa
450 91 xd = xb - xa; xe = xd
451
452
3/4
✓ Branch 14 → 15 taken 516 times.
✓ Branch 14 → 42 taken 21 times.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 516 times.
537 do while (flag == 1 .and. fb /= 0 .and. xa /= xb)
453
454 ! Ensure that b is the best result so far, a is the previous
455 ! value of b, and c is on the opposite side of the zero from b.
456
2/2
✓ Branch 17 → 18 taken 268 times.
✓ Branch 17 → 19 taken 248 times.
516 if (fb * fc > 0) then
457 xc = xa; fc = fa
458 268 xd = xb - xa; xe = xd
459 endif
460
2/2
✓ Branch 19 → 20 taken 157 times.
✓ Branch 19 → 21 taken 359 times.
516 if (abs(fc) < abs(fb)) then
461 157 xa = xb; xb = xc; xc = xa
462 fa = fb; fb = fc; fc = fa
463 endif
464
465 ! Convergence test and possible exit
466 516 xm = 0.5*(xc - xb)
467
468 516 toler = x_tol
469
3/4
✓ Branch 21 → 22 taken 446 times.
✓ Branch 21 → 43 taken 70 times.
✓ Branch 22 → 23 taken 446 times.
✗ Branch 22 → 43 not taken.
516 if ((abs(xm) <= toler) .or. (fb == 0.0)) then
470 flag = 0
471 exit
472
1/2
✓ Branch 23 → 24 taken 446 times.
✗ Branch 23 → 43 not taken.
446 elseif (iter == max_iter) then
473 flag = -1
474 exit
475 endif
476
477 ! Choose bisection or interpolation
478
2/4
✓ Branch 24 → 25 taken 446 times.
✗ Branch 24 → 35 not taken.
✓ Branch 25 → 26 taken 446 times.
✗ Branch 25 → 35 not taken.
446 if ((abs(xe) < toler) .or. (abs(fa) <= abs(fb))) then
479 ! Bisection
480 xd = xm; xe = xm
481 else
482 ! Interpolation
483 446 s = fb/fa;
484
2/2
✓ Branch 26 → 27 taken 268 times.
✓ Branch 26 → 28 taken 178 times.
446 if (xa == xc) then
485 ! Linear interpolation
486 268 p = 2*xm*s
487 268 q = 1 - s
488 else
489 ! Inverse quadratic interpolation
490 178 q = fa/fc
491 178 r = fb/fc
492 178 p = s*(2*xm*q*(q - r) - (xb - xa)*(r - 1))
493 178 q = (q - 1)*(r - 1)*(s - 1)
494 endif
495
2/2
✓ Branch 29 → 30 taken 276 times.
✓ Branch 29 → 31 taken 170 times.
446 if (p > 0) then
496 276 q = -q
497 else
498 170 p = -p
499 endif
500 ! Is interpolated point acceptable
501
3/4
✓ Branch 32 → 33 taken 390 times.
✓ Branch 32 → 35 taken 56 times.
✓ Branch 33 → 34 taken 390 times.
✗ Branch 33 → 35 not taken.
446 if ((2*p < 3*xm*q - abs(toler*q)) .and. (p < abs(0.5*xe*q))) then
502 390 xe = xd; xd = p/q
503 else
504 xd = xm; xe = xm
505 endif
506 endif ! Interpolation
507
508 ! Next point
509 446 xa = xb
510 fa = fb
511
2/2
✓ Branch 35 → 36 taken 376 times.
✓ Branch 35 → 37 taken 70 times.
446 if (abs(xd) > toler) then
512 376 xb = xb + xd
513
2/2
✓ Branch 37 → 38 taken 33 times.
✓ Branch 37 → 39 taken 37 times.
70 elseif (xb > xc) then
514 33 xb = xb - toler
515 else
516 37 xb = xb + toler
517 endif
518 446 fb = fun(xb)
519 446 iter = iter + 1
520
521 end do
522
523 91 xsol = xb
524
525
1/6
✗ Branch 43 → 44 not taken.
✓ Branch 43 → 47 taken 91 times.
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 46 not taken.
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 47 not taken.
91 if (flag == 1 .and. (fb == 0 .or. xa == xb)) then
526 flag = 0
527 end if
528
529
1/2
✓ Branch 47 → 48 taken 91 times.
✗ Branch 47 → 49 not taken.
91 if (present(success)) success = flag == 0
530
531 91 end function
532
533 end submodule
534