@@ -105,33 +105,33 @@ end of this document shows that is the case.
105105### Example
106106
107107``` fortran
108- program demo_select
109- use stdlib_selection, only: select
110- implicit none
108+ program demo_select
109+ use stdlib_selection, only: select
110+ implicit none
111111
112- real, allocatable :: array(:)
113- real :: kth_smallest
114- integer :: k, left, right
112+ real, allocatable :: array(:)
113+ real :: kth_smallest
114+ integer :: k, left, right
115115
116- array = [3., 2., 7., 4., 5., 1., 4., -1.]
116+ array = [3., 2., 7., 4., 5., 1., 4., -1.]
117117
118- k = 2
119- call select(array, k, kth_smallest)
120- print*, kth_smallest ! print 1.0
118+ k = 2
119+ call select(array, k, kth_smallest)
120+ print*, kth_smallest ! print 1.0
121121
122- k = 7
123- ! Due to the previous call to select, we know for sure this is in an
124- ! index >= 2
125- call select(array, k, kth_smallest, left=2)
126- print*, kth_smallest ! print 5.0
122+ k = 7
123+ ! Due to the previous call to select, we know for sure this is in an
124+ ! index >= 2
125+ call select(array, k, kth_smallest, left=2)
126+ print*, kth_smallest ! print 5.0
127127
128- k = 6
129- ! Due to the previous two calls to select, we know for sure this is in
130- ! an index >= 2 and <= 7
131- call select(array, k, kth_smallest, left=2, right=7)
132- print*, kth_smallest ! print 4.0
128+ k = 6
129+ ! Due to the previous two calls to select, we know for sure this is in
130+ ! an index >= 2 and <= 7
131+ call select(array, k, kth_smallest, left=2, right=7)
132+ print*, kth_smallest ! print 4.0
133133
134- end program demo_select
134+ end program demo_select
135135```
136136
137137## ` arg_select ` - find the index of the k-th smallest value in an input array
@@ -204,35 +204,35 @@ these documents confirms that is the case.
204204
205205
206206``` fortran
207- program demo_arg_select
208- use stdlib_selection, only: arg_select
209- implicit none
210-
211- real, allocatable :: array(:)
212- integer, allocatable :: indx(:)
213- integer :: kth_smallest
214- integer :: k, left, right
215-
216- array = [3., 2., 7., 4., 5., 1., 4., -1.]
217- indx = [( k, k = 1, size(array) )]
218-
219- k = 2
220- call arg_select(array, indx, k, kth_smallest)
221- print*, array(kth_smallest) ! print 1.0
222-
223- k = 7
224- ! Due to the previous call to arg_select, we know for sure this is in an
225- ! index >= 2
226- call arg_select(array, indx, k, kth_smallest, left=2)
227- print*, array(kth_smallest) ! print 5.0
228-
229- k = 6
230- ! Due to the previous two calls to arg_select, we know for sure this is in
231- ! an index >= 2 and <= 7
232- call arg_select(array, indx, k, kth_smallest, left=2, right=7)
233- print*, array(kth_smallest) ! print 4.0
234-
235- end program demo_arg_select
207+ program demo_arg_select
208+ use stdlib_selection, only: arg_select
209+ implicit none
210+
211+ real, allocatable :: array(:)
212+ integer, allocatable :: indx(:)
213+ integer :: kth_smallest
214+ integer :: k, left, right
215+
216+ array = [3., 2., 7., 4., 5., 1., 4., -1.]
217+ indx = [( k, k = 1, size(array) )]
218+
219+ k = 2
220+ call arg_select(array, indx, k, kth_smallest)
221+ print*, array(kth_smallest) ! print 1.0
222+
223+ k = 7
224+ ! Due to the previous call to arg_select, we know for sure this is in an
225+ ! index >= 2
226+ call arg_select(array, indx, k, kth_smallest, left=2)
227+ print*, array(kth_smallest) ! print 5.0
228+
229+ k = 6
230+ ! Due to the previous two calls to arg_select, we know for sure this is in
231+ ! an index >= 2 and <= 7
232+ call arg_select(array, indx, k, kth_smallest, left=2, right=7)
233+ print*, array(kth_smallest) ! print 4.0
234+
235+ end program demo_arg_select
236236```
237237
238238## Comparison with using ` sort `
@@ -243,84 +243,83 @@ should see a speed improvement with the selection routines which grows like
243243LOG(size(` array ` )).
244244
245245``` fortran
246- program selection_vs_sort
247- use stdlib_kinds, only: dp, sp, int64
248- use stdlib_selection, only: select, arg_select
249- use stdlib_sorting, only: sort
250- implicit none
251-
252- call compare_select_sort_for_median(1)
253- call compare_select_sort_for_median(11)
254- call compare_select_sort_for_median(101)
255- call compare_select_sort_for_median(1001)
256- call compare_select_sort_for_median(10001)
257- call compare_select_sort_for_median(100001)
258-
259-
260- contains
261- subroutine compare_select_sort_for_median(N)
262- integer, intent(in) :: N
263-
264- integer :: i, k, result_arg_select, indx(N), indx_local(N)
265- real :: random_vals(N), local_random_vals(N)
266- integer, parameter :: test_reps = 100
267- integer(int64) :: t0, t1
268- real :: result_sort, result_select
269- integer(int64) :: time_sort, time_select, time_arg_select
270- logical :: select_test_passed, arg_select_test_passed
271-
272- ! Ensure N is odd
273- if(mod(N, 2) /= 1) stop
274-
275- time_sort = 0
276- time_select = 0
277- time_arg_select = 0
278-
279- select_test_passed = .true.
280- arg_select_test_passed = .true.
281-
282- indx = (/( i, i = 1, N) /)
283-
284- k = (N+1)/2 ! Deliberate integer division
285-
286- do i = 1, test_reps
287- call random_number(random_vals)
288-
289- ! Compute the median with sorting
290- local_random_vals = random_vals
291- call system_clock(t0)
292- call sort(local_random_vals)
293- result_sort = local_random_vals(k)
294- call system_clock(t1)
295- time_sort = time_sort + (t1 - t0)
296-
297- ! Compute the median with selection, assuming N is odd
298- local_random_vals = random_vals
299- call system_clock(t0)
300- call select(local_random_vals, k, result_select)
301- call system_clock(t1)
302- time_select = time_select + (t1 - t0)
303-
304- ! Compute the median with arg_select, assuming N is odd
305- local_random_vals = random_vals
306- indx_local = indx
307- call system_clock(t0)
308- call arg_select(local_random_vals, indx_local, k, result_arg_select)
309- call system_clock(t1)
310- time_arg_select = time_arg_select + (t1 - t0)
311-
312- if(result_select /= result_sort) select_test_passed = .FALSE.
313- if(local_random_vals(result_arg_select) /= result_sort) arg_select_test_passed = .FALSE.
314- end do
315-
316- print*, "select ; N=", N, '; ', merge('PASS', 'FAIL', select_test_passed), &
317- '; Relative-speedup-vs-sort:', (1.0*time_sort)/(1.0*time_select)
318- print*, "arg_select; N=", N, '; ', merge('PASS', 'FAIL', arg_select_test_passed), &
319- '; Relative-speedup-vs-sort:', (1.0*time_sort)/(1.0*time_arg_select)
320-
321- end subroutine
322-
323- end program
246+ program selection_vs_sort
247+ use stdlib_kinds, only: dp, sp, int64
248+ use stdlib_selection, only: select, arg_select
249+ use stdlib_sorting, only: sort
250+ implicit none
251+
252+ call compare_select_sort_for_median(1)
253+ call compare_select_sort_for_median(11)
254+ call compare_select_sort_for_median(101)
255+ call compare_select_sort_for_median(1001)
256+ call compare_select_sort_for_median(10001)
257+ call compare_select_sort_for_median(100001)
258+
259+ contains
260+ subroutine compare_select_sort_for_median(N)
261+ integer, intent(in) :: N
262+
263+ integer :: i, k, result_arg_select, indx(N), indx_local(N)
264+ real :: random_vals(N), local_random_vals(N)
265+ integer, parameter :: test_reps = 100
266+ integer(int64) :: t0, t1
267+ real :: result_sort, result_select
268+ integer(int64) :: time_sort, time_select, time_arg_select
269+ logical :: select_test_passed, arg_select_test_passed
270+
271+ ! Ensure N is odd
272+ if(mod(N, 2) /= 1) stop
273+
274+ time_sort = 0
275+ time_select = 0
276+ time_arg_select = 0
277+
278+ select_test_passed = .true.
279+ arg_select_test_passed = .true.
280+
281+ indx = (/( i, i = 1, N) /)
282+
283+ k = (N+1)/2 ! Deliberate integer division
284+
285+ do i = 1, test_reps
286+ call random_number(random_vals)
287+
288+ ! Compute the median with sorting
289+ local_random_vals = random_vals
290+ call system_clock(t0)
291+ call sort(local_random_vals)
292+ result_sort = local_random_vals(k)
293+ call system_clock(t1)
294+ time_sort = time_sort + (t1 - t0)
295+
296+ ! Compute the median with selection, assuming N is odd
297+ local_random_vals = random_vals
298+ call system_clock(t0)
299+ call select(local_random_vals, k, result_select)
300+ call system_clock(t1)
301+ time_select = time_select + (t1 - t0)
302+
303+ ! Compute the median with arg_select, assuming N is odd
304+ local_random_vals = random_vals
305+ indx_local = indx
306+ call system_clock(t0)
307+ call arg_select(local_random_vals, indx_local, k, result_arg_select)
308+ call system_clock(t1)
309+ time_arg_select = time_arg_select + (t1 - t0)
310+
311+ if(result_select /= result_sort) select_test_passed = .FALSE.
312+ if(local_random_vals(result_arg_select) /= result_sort) arg_select_test_passed = .FALSE.
313+ end do
314+
315+ print*, "select ; N=", N, '; ', merge('PASS', 'FAIL', select_test_passed), &
316+ '; Relative-speedup-vs-sort:', (1.0*time_sort)/(1.0*time_select)
317+ print*, "arg_select; N=", N, '; ', merge('PASS', 'FAIL', arg_select_test_passed), &
318+ '; Relative-speedup-vs-sort:', (1.0*time_sort)/(1.0*time_arg_select)
319+
320+ end subroutine
321+
322+ end program
324323```
325324
326325The results seem consistent with expectations when the ` array ` is large; the program prints:
0 commit comments