@@ -7,10 +7,7 @@ submodule (stdlib_stats) stdlib_stats_median
7
7
use, intrinsic:: ieee_arithmetic, only: ieee_value, ieee_quiet_nan, ieee_is_nan
8
8
use stdlib_error, only: error_stop
9
9
use stdlib_optval, only: optval
10
- ! Use "ord_sort" rather than "sort" because the former can be much faster for arrays
11
- ! that are already partly sorted. While it is slightly slower for random arrays,
12
- ! ord_sort seems a better overall choice.
13
- use stdlib_sorting, only: sort => ord_sort
10
+ use stdlib_selection, only: select
14
11
implicit none
15
12
16
13
contains
@@ -24,6 +21,7 @@ contains
24
21
real(${o1}$) :: res
25
22
26
23
integer(kind = int64) :: c, n
24
+ ${t1}$ :: val, val1
27
25
${t1}$, allocatable :: x_tmp(:)
28
26
29
27
if (.not.optval(mask, .true.) .or. size(x) == 0) then
@@ -43,16 +41,18 @@ contains
43
41
44
42
x_tmp = reshape(x, [n])
45
43
46
- call sort (x_tmp)
44
+ call select (x_tmp, c, val )
47
45
48
46
if (mod(n, 2_int64) == 0) then
47
+ val1 = minval(x_tmp(c+1:n)) !instead of call select(x_tmp, c+1, val1, left = c)
49
48
#:if t1[0] == 'r'
50
- res = sum(x_tmp(c:c+1) ) / 2._${o1}$
49
+ res = (val + val1 ) / 2._${o1}$
51
50
#:else
52
- res = sum( real(x_tmp(c:c+1), kind=${o1}$) ) / 2._${o1}$
51
+ res = (real(val, kind=${o1}$) + &
52
+ real(val1, kind=${o1}$)) / 2._${o1}$
53
53
#:endif
54
54
else
55
- res = x_tmp(c)
55
+ res = val
56
56
end if
57
57
58
58
end function ${name}$
@@ -74,6 +74,7 @@ contains
74
74
integer :: j${fj}$
75
75
#:endfor
76
76
#:endif
77
+ ${t1}$ :: val, val1
77
78
${t1}$, allocatable :: x_tmp(:)
78
79
79
80
if (.not.optval(mask, .true.) .or. size(x) == 0) then
@@ -107,17 +108,18 @@ contains
107
108
end if
108
109
#:endif
109
110
110
- call sort (x_tmp)
111
+ call select (x_tmp, c, val )
111
112
112
113
if (mod(n, 2) == 0) then
114
+ val1 = minval(x_tmp(c+1:n))
113
115
res${reduce_subvector('j', rank, fi)}$ = &
114
116
#:if t1[0] == 'r'
115
- sum(x_tmp(c:c+1) ) / 2._${o1}$
117
+ (val + val1 ) / 2._${o1}$
116
118
#:else
117
- sum (real(x_tmp(c:c+1) , kind=${o1}$) ) / 2._${o1}$
119
+ (real(val , kind=${o1}$) + real(val1, kind=${o1}$) ) / 2._${o1}$
118
120
#:endif
119
121
else
120
- res${reduce_subvector('j', rank, fi)}$ = x_tmp(c)
122
+ res${reduce_subvector('j', rank, fi)}$ = val
121
123
end if
122
124
#:for fj in range(1, rank)
123
125
end do
@@ -141,6 +143,7 @@ contains
141
143
real(${o1}$) :: res
142
144
143
145
integer(kind = int64) :: c, n
146
+ ${t1}$ :: val, val1
144
147
${t1}$, allocatable :: x_tmp(:)
145
148
146
149
if (any(shape(x) .ne. shape(mask))) then
@@ -156,21 +159,26 @@ contains
156
159
157
160
x_tmp = pack(x, mask)
158
161
159
- call sort(x_tmp)
160
-
161
162
n = size(x_tmp, kind=int64)
162
- c = floor( (n + 1) / 2._${o1}$, kind=int64)
163
163
164
164
if (n == 0) then
165
165
res = ieee_value(1._${o1}$, ieee_quiet_nan)
166
- else if (mod(n, 2_int64) == 0) then
166
+ return
167
+ end if
168
+
169
+ c = floor( (n + 1) / 2._${o1}$, kind=int64)
170
+
171
+ call select(x_tmp, c, val)
172
+
173
+ if (mod(n, 2_int64) == 0) then
174
+ val1 = minval(x_tmp(c+1:n))
167
175
#:if t1[0] == 'r'
168
- res = sum(x_tmp(c:c+1) ) / 2._${o1}$
176
+ res = (val + val1 ) / 2._${o1}$
169
177
#:else
170
- res = sum (real(x_tmp(c:c+1) , kind=${o1}$)) / 2._${o1}$
178
+ res = (real(val, kind=${o1}$) + real(val1 , kind=${o1}$)) / 2._${o1}$
171
179
#:endif
172
180
else if (mod(n, 2_int64) == 1) then
173
- res = x_tmp(c)
181
+ res = val
174
182
end if
175
183
176
184
end function ${name}$
@@ -192,6 +200,7 @@ contains
192
200
integer :: j${fj}$
193
201
#:endfor
194
202
#:endif
203
+ ${t1}$ :: val, val1
195
204
${t1}$, allocatable :: x_tmp(:)
196
205
197
206
if (any(shape(x) .ne. shape(mask))) then
@@ -220,23 +229,28 @@ contains
220
229
end if
221
230
#:endif
222
231
223
- call sort(x_tmp)
224
-
225
232
n = size(x_tmp, kind=int64)
226
- c = floor( (n + 1) / 2._${o1}$, kind=int64 )
227
233
228
234
if (n == 0) then
229
235
res${reduce_subvector('j', rank, fi)}$ = &
230
236
ieee_value(1._${o1}$, ieee_quiet_nan)
231
- else if (mod(n, 2_int64) == 0) then
237
+ return
238
+ end if
239
+
240
+ c = floor( (n + 1) / 2._${o1}$, kind=int64 )
241
+
242
+ call select(x_tmp, c, val)
243
+
244
+ if (mod(n, 2_int64) == 0) then
245
+ val1 = minval(x_tmp(c+1:n))
232
246
res${reduce_subvector('j', rank, fi)}$ = &
233
247
#:if t1[0] == 'r'
234
- sum(x_tmp(c:c+1) ) / 2._${o1}$
248
+ (val + val1 ) / 2._${o1}$
235
249
#:else
236
- sum (real(x_tmp(c:c+1) , kind=${o1}$)) / 2._${o1}$
250
+ (real(val, kind=${o1}$) + real(val1 , kind=${o1}$)) / 2._${o1}$
237
251
#:endif
238
252
else if (mod(n, 2_int64) == 1) then
239
- res${reduce_subvector('j', rank, fi)}$ = x_tmp(c)
253
+ res${reduce_subvector('j', rank, fi)}$ = val
240
254
end if
241
255
242
256
deallocate(x_tmp)
0 commit comments