@@ -1135,7 +1135,7 @@ end
1135
1135
module Float
1136
1136
using .. Sort
1137
1137
using ... Order
1138
- using .. Base: @inbounds , AbstractVector, Vector, last, axes
1138
+ using .. Base: @inbounds , AbstractVector, Vector, last, axes, Missing
1139
1139
1140
1140
import Core. Intrinsics: slt_int
1141
1141
import .. Sort: sort!
@@ -1156,31 +1156,43 @@ lt(::Left, x::T, y::T) where {T<:Floats} = slt_int(y, x)
1156
1156
lt (:: Right , x:: T , y:: T ) where {T<: Floats } = slt_int (x, y)
1157
1157
1158
1158
isnan (o:: DirectOrdering , x:: Floats ) = (x!= x)
1159
+ isnan (o:: DirectOrdering , x:: Missing ) = false
1159
1160
isnan (o:: Perm , i:: Integer ) = isnan (o. order,o. data[i])
1160
1161
1161
- function nans2left! (v:: AbstractVector , o:: Ordering , lo:: Integer = first (axes (v,1 )), hi:: Integer = last (axes (v,1 )))
1162
+ ismissing (o:: DirectOrdering , x:: Floats ) = false
1163
+ ismissing (o:: DirectOrdering , x:: Missing ) = true
1164
+ ismissing (o:: Perm , i:: Int ) = ismissing (o. order,o. data[i])
1165
+
1166
+ allowsmissing (:: AbstractVector{T} , :: DirectOrdering ) where {T} = T >: Missing
1167
+ allowsmissing (:: AbstractVector{Int} ,
1168
+ :: Perm{<:DirectOrdering,<:AbstractVector{T}} ) where {T} =
1169
+ T >: Missing
1170
+
1171
+ function specials2left! (testf:: Function , v:: AbstractVector , o:: Ordering ,
1172
+ lo:: Integer = first (axes (v,1 )), hi:: Integer = last (axes (v,1 )))
1162
1173
i = lo
1163
- @inbounds while i <= hi && isnan (o,v[i])
1174
+ @inbounds while i <= hi && testf (o,v[i])
1164
1175
i += 1
1165
1176
end
1166
1177
j = i + 1
1167
1178
@inbounds while j <= hi
1168
- if isnan (o,v[j])
1179
+ if testf (o,v[j])
1169
1180
v[i], v[j] = v[j], v[i]
1170
1181
i += 1
1171
1182
end
1172
1183
j += 1
1173
1184
end
1174
1185
return i, hi
1175
1186
end
1176
- function nans2right! (v:: AbstractVector , o:: Ordering , lo:: Integer = first (axes (v,1 )), hi:: Integer = last (axes (v,1 )))
1187
+ function specials2right! (testf:: Function , v:: AbstractVector , o:: Ordering ,
1188
+ lo:: Integer = first (axes (v,1 )), hi:: Integer = last (axes (v,1 )))
1177
1189
i = hi
1178
- @inbounds while lo <= i && isnan (o,v[i])
1190
+ @inbounds while lo <= i && testf (o,v[i])
1179
1191
i -= 1
1180
1192
end
1181
1193
j = i - 1
1182
1194
@inbounds while lo <= j
1183
- if isnan (o,v[j])
1195
+ if testf (o,v[j])
1184
1196
v[i], v[j] = v[j], v[i]
1185
1197
i -= 1
1186
1198
end
@@ -1189,17 +1201,42 @@ function nans2right!(v::AbstractVector, o::Ordering, lo::Integer=first(axes(v,1)
1189
1201
return lo, i
1190
1202
end
1191
1203
1192
- nans2end! (v:: AbstractVector , o:: ForwardOrdering ) = nans2right! (v,o)
1193
- nans2end! (v:: AbstractVector , o:: ReverseOrdering ) = nans2left! (v,o)
1194
- nans2end! (v:: AbstractVector{<:Integer} , o:: Perm{<:ForwardOrdering} ) = nans2right! (v,o)
1195
- nans2end! (v:: AbstractVector{<:Integer} , o:: Perm{<:ReverseOrdering} ) = nans2left! (v,o)
1204
+ function specials2left! (v:: AbstractVector , a:: Algorithm , o:: Ordering )
1205
+ lo, hi = first (axes (v,1 )), last (axes (v,1 ))
1206
+ if allowsmissing (v, o)
1207
+ i, _ = specials2left! ((v, o) -> ismissing (v, o) || isnan (v, o), v, o, lo, hi)
1208
+ sort! (v, lo, i- 1 , a, o)
1209
+ return i, hi
1210
+ else
1211
+ return specials2left! (isnan, v, o, lo, hi)
1212
+ end
1213
+ end
1214
+ function specials2right! (v:: AbstractVector , a:: Algorithm , o:: Ordering )
1215
+ lo, hi = first (axes (v,1 )), last (axes (v,1 ))
1216
+ if allowsmissing (v, o)
1217
+ _, i = specials2right! ((v, o) -> ismissing (v, o) || isnan (v, o), v, o, lo, hi)
1218
+ sort! (v, i+ 1 , hi, a, o)
1219
+ return lo, i
1220
+ else
1221
+ return specials2right! (isnan, v, o, lo, hi)
1222
+ end
1223
+ end
1224
+
1225
+ specials2end! (v:: AbstractVector , a:: Algorithm , o:: ForwardOrdering ) =
1226
+ specials2right! (v, a, o)
1227
+ specials2end! (v:: AbstractVector , a:: Algorithm , o:: ReverseOrdering ) =
1228
+ specials2left! (v, a, o)
1229
+ specials2end! (v:: AbstractVector{<:Integer} , a:: Algorithm , o:: Perm{<:ForwardOrdering} ) =
1230
+ specials2right! (v, a, o)
1231
+ specials2end! (v:: AbstractVector{<:Integer} , a:: Algorithm , o:: Perm{<:ReverseOrdering} ) =
1232
+ specials2left! (v, a, o)
1196
1233
1197
1234
issignleft (o:: ForwardOrdering , x:: Floats ) = lt (o, x, zero (x))
1198
1235
issignleft (o:: ReverseOrdering , x:: Floats ) = lt (o, x, - zero (x))
1199
1236
issignleft (o:: Perm , i:: Integer ) = issignleft (o. order, o. data[i])
1200
1237
1201
1238
function fpsort! (v:: AbstractVector , a:: Algorithm , o:: Ordering )
1202
- i, j = lo, hi = nans2end ! (v,o)
1239
+ i, j = lo, hi = specials2end ! (v,a ,o)
1203
1240
@inbounds while true
1204
1241
while i <= j && issignleft (o,v[i]); i += 1 ; end
1205
1242
while i <= j && ! issignleft (o,v[j]); j -= 1 ; end
@@ -1216,8 +1253,10 @@ end
1216
1253
fpsort! (v:: AbstractVector , a:: Sort.PartialQuickSort , o:: Ordering ) =
1217
1254
sort! (v, first (axes (v,1 )), last (axes (v,1 )), a, o)
1218
1255
1219
- sort! (v:: AbstractVector{<:Floats} , a:: Algorithm , o:: DirectOrdering ) = fpsort! (v,a,o)
1220
- sort! (v:: Vector{Int} , a:: Algorithm , o:: Perm{<:DirectOrdering,<:Vector{<:Floats}} ) = fpsort! (v,a,o)
1256
+ sort! (v:: AbstractVector{<:Union{Floats, Missing}} , a:: Algorithm , o:: DirectOrdering ) =
1257
+ fpsort! (v,a,o)
1258
+ sort! (v:: Vector{Int} , a:: Algorithm , o:: Perm{<:DirectOrdering,<:Vector{<:Union{Floats, Missing}}} ) =
1259
+ fpsort! (v,a,o)
1221
1260
1222
1261
end # module Sort.Float
1223
1262
0 commit comments