@@ -67,105 +67,6 @@ function sort!(v::AbstractVector, lo::Int, hi::Int, a::HeapSortAlg, o::Ordering)
6767end
6868
6969
70- # # Radix sort
71-
72- # Map a bits-type to an unsigned int, maintaining sort order
73- uint_mapping (:: ForwardOrdering , x:: Unsigned ) = x
74- for (signedty, unsignedty) in ((Int8, UInt8), (Int16, UInt16), (Int32, UInt32), (Int64, UInt64), (Int128, UInt128))
75- # In Julia 0.4 we can just use unsigned() here
76- @eval uint_mapping (:: ForwardOrdering , x:: $signedty ) = reinterpret ($ unsignedty, xor (x, typemin (typeof (x))))
77- end
78- uint_mapping (:: ForwardOrdering , x:: Float32 ) = (y = reinterpret (Int32, x); reinterpret (UInt32, ifelse (y < 0 , ~ y, xor (y, typemin (Int32)))))
79- uint_mapping (:: ForwardOrdering , x:: Float64 ) = (y = reinterpret (Int64, x); reinterpret (UInt64, ifelse (y < 0 , ~ y, xor (y, typemin (Int64)))))
80-
81- uint_mapping (:: Sort.Float.Left , x:: Float16 ) = ~ reinterpret (Int16, x)
82- uint_mapping (:: Sort.Float.Right , x:: Float16 ) = reinterpret (Int16, x)
83- uint_mapping (:: Sort.Float.Left , x:: Float32 ) = ~ reinterpret (Int32, x)
84- uint_mapping (:: Sort.Float.Right , x:: Float32 ) = reinterpret (Int32, x)
85- uint_mapping (:: Sort.Float.Left , x:: Float64 ) = ~ reinterpret (Int64, x)
86- uint_mapping (:: Sort.Float.Right , x:: Float64 ) = reinterpret (Int64, x)
87-
88- uint_mapping (rev:: ReverseOrdering , x) = ~ uint_mapping (rev. fwd, x)
89- uint_mapping (:: ReverseOrdering{ForwardOrdering} , x:: Real ) = ~ uint_mapping (Forward, x) # maybe unnecessary; needs benchmark
90-
91- uint_mapping (o:: By , x ) = uint_mapping (Forward, o. by (x))
92- uint_mapping (o:: Perm , i:: Int ) = uint_mapping (o. order, o. data[i])
93- uint_mapping (o:: Lt , x ) = error (" uint_mapping does not work with general Lt Orderings" )
94-
95- const RADIX_SIZE = 11
96- const RADIX_MASK = 0x7FF
97-
98- function sort! (vs:: AbstractVector{T} , lo:: Int , hi:: Int , :: RadixSortAlg , o:: Ordering , ts:: AbstractVector{T} = similar (vs)) where T
99- # Input checking
100- if lo >= hi; return vs; end
101-
102- # Make sure we're sorting a bits type
103- OT = Base. Order. ordtype (o, vs)
104- if ! isbitstype (OT)
105- error (" Radix sort only sorts bits types (got $OT )" )
106- end
107-
108- # Init
109- iters = ceil (Integer, sizeof (OT)* 8 / RADIX_SIZE)
110- bin = zeros (UInt32, 2 ^ RADIX_SIZE, iters)
111- if lo > 1 ; bin[1 ,:] .= lo- 1 ; end
112-
113- # Histogram for each element, radix
114- for i = lo: hi
115- v = uint_mapping (o, vs[i])
116- for j = 1 : iters
117- idx = Int ((v >> ((j- 1 )* RADIX_SIZE)) & RADIX_MASK) + 1
118- @inbounds bin[idx,j] += 1
119- end
120- end
121-
122- # Sort!
123- swaps = 0
124- len = hi- lo+ 1
125- for j = 1 : iters
126- # Unroll first data iteration, check for degenerate case
127- v = uint_mapping (o, vs[hi])
128- idx = Int ((v >> ((j- 1 )* RADIX_SIZE)) & RADIX_MASK) + 1
129-
130- # are all values the same at this radix?
131- if bin[idx,j] == len; continue ; end
132-
133- cbin = cumsum (bin[:,j])
134- ci = cbin[idx]
135- ts[ci] = vs[hi]
136- cbin[idx] -= 1
137-
138- # Finish the loop...
139- @inbounds for i in hi- 1 : - 1 : lo
140- v = uint_mapping (o, vs[i])
141- idx = Int ((v >> ((j- 1 )* RADIX_SIZE)) & RADIX_MASK) + 1
142- ci = cbin[idx]
143- ts[ci] = vs[i]
144- cbin[idx] -= 1
145- end
146- vs,ts = ts,vs
147- swaps += 1
148- end
149-
150- if isodd (swaps)
151- vs,ts = ts,vs
152- for i = lo: hi
153- vs[i] = ts[i]
154- end
155- end
156- vs
157- end
158-
159- function Base. Sort. Float. fpsort! (v:: AbstractVector , :: RadixSortAlg , o:: Ordering )
160- @static if VERSION >= v " 1.7.0-DEV"
161- lo, hi = Base. Sort. Float. specials2end! (v, RadixSort, o)
162- else
163- lo, hi = Base. Sort. Float. nans2end! (v, o)
164- end
165- sort! (v, lo, hi, RadixSort, o)
166- end
167-
168-
16970# Implementation of TimSort based on the algorithm description at:
17071#
17172# http://svn.python.org/projects/python/trunk/Objects/listsort.txt
@@ -605,6 +506,7 @@ function sort!(v::AbstractVector, lo::Int, hi::Int, ::TimSortAlg, o::Ordering)
605506 return v
606507end
607508
509+
608510function sort! (v:: AbstractVector , lo:: Int , hi:: Int , :: CombSortAlg , o:: Ordering )
609511 interval = (3 * (hi- lo+ 1 )) >> 2
610512
@@ -619,4 +521,109 @@ function sort!(v::AbstractVector, lo::Int, hi::Int, ::CombSortAlg, o::Ordering)
619521 return sort! (v, lo, hi, InsertionSort, o)
620522end
621523
524+
525+ # # Radix sort
526+ @static if VERSION >= v " 1.9.0-DEV.482" # Base introduced radixsort in 1.9
527+ function sort! (vs:: AbstractVector{T} , lo:: Int , hi:: Int , :: RadixSortAlg , o:: Ordering , ts:: Union{Nothing, AbstractVector{T}} = nothing ) where T
528+ sort! (vs, lo, hi, Base. DEFAULT_STABLE, o)
529+ end
530+ else
531+
532+ # Map a bits-type to an unsigned int, maintaining sort order
533+ uint_mapping (:: ForwardOrdering , x:: Unsigned ) = x
534+ for (signedty, unsignedty) in ((Int8, UInt8), (Int16, UInt16), (Int32, UInt32), (Int64, UInt64), (Int128, UInt128))
535+ # In Julia 0.4 we can just use unsigned() here
536+ @eval uint_mapping (:: ForwardOrdering , x:: $signedty ) = reinterpret ($ unsignedty, xor (x, typemin (typeof (x))))
537+ end
538+ uint_mapping (:: ForwardOrdering , x:: Float32 ) = (y = reinterpret (Int32, x); reinterpret (UInt32, ifelse (y < 0 , ~ y, xor (y, typemin (Int32)))))
539+ uint_mapping (:: ForwardOrdering , x:: Float64 ) = (y = reinterpret (Int64, x); reinterpret (UInt64, ifelse (y < 0 , ~ y, xor (y, typemin (Int64)))))
540+
541+ uint_mapping (:: Sort.Float.Left , x:: Float16 ) = ~ reinterpret (Int16, x)
542+ uint_mapping (:: Sort.Float.Right , x:: Float16 ) = reinterpret (Int16, x)
543+ uint_mapping (:: Sort.Float.Left , x:: Float32 ) = ~ reinterpret (Int32, x)
544+ uint_mapping (:: Sort.Float.Right , x:: Float32 ) = reinterpret (Int32, x)
545+ uint_mapping (:: Sort.Float.Left , x:: Float64 ) = ~ reinterpret (Int64, x)
546+ uint_mapping (:: Sort.Float.Right , x:: Float64 ) = reinterpret (Int64, x)
547+
548+ uint_mapping (rev:: ReverseOrdering , x) = ~ uint_mapping (rev. fwd, x)
549+ uint_mapping (:: ReverseOrdering{ForwardOrdering} , x:: Real ) = ~ uint_mapping (Forward, x) # maybe unnecessary; needs benchmark
550+
551+ uint_mapping (o:: By , x ) = uint_mapping (Forward, o. by (x))
552+ uint_mapping (o:: Perm , i:: Int ) = uint_mapping (o. order, o. data[i])
553+ uint_mapping (o:: Lt , x ) = error (" uint_mapping does not work with general Lt Orderings" )
554+
555+ const RADIX_SIZE = 11
556+ const RADIX_MASK = 0x7FF
557+
558+ function sort! (vs:: AbstractVector{T} , lo:: Int , hi:: Int , :: RadixSortAlg , o:: Ordering , ts:: AbstractVector{T} = similar (vs)) where T
559+ # Input checking
560+ if lo >= hi; return vs; end
561+
562+ # Make sure we're sorting a bits type
563+ OT = Base. Order. ordtype (o, vs)
564+ if ! isbitstype (OT)
565+ error (" Radix sort only sorts bits types (got $OT )" )
566+ end
567+
568+ # Init
569+ iters = ceil (Integer, sizeof (OT)* 8 / RADIX_SIZE)
570+ bin = zeros (UInt32, 2 ^ RADIX_SIZE, iters)
571+ if lo > 1 ; bin[1 ,:] .= lo- 1 ; end
572+
573+ # Histogram for each element, radix
574+ for i = lo: hi
575+ v = uint_mapping (o, vs[i])
576+ for j = 1 : iters
577+ idx = Int ((v >> ((j- 1 )* RADIX_SIZE)) & RADIX_MASK) + 1
578+ @inbounds bin[idx,j] += 1
579+ end
580+ end
581+
582+ # Sort!
583+ swaps = 0
584+ len = hi- lo+ 1
585+ for j = 1 : iters
586+ # Unroll first data iteration, check for degenerate case
587+ v = uint_mapping (o, vs[hi])
588+ idx = Int ((v >> ((j- 1 )* RADIX_SIZE)) & RADIX_MASK) + 1
589+
590+ # are all values the same at this radix?
591+ if bin[idx,j] == len; continue ; end
592+
593+ cbin = cumsum (bin[:,j])
594+ ci = cbin[idx]
595+ ts[ci] = vs[hi]
596+ cbin[idx] -= 1
597+
598+ # Finish the loop...
599+ @inbounds for i in hi- 1 : - 1 : lo
600+ v = uint_mapping (o, vs[i])
601+ idx = Int ((v >> ((j- 1 )* RADIX_SIZE)) & RADIX_MASK) + 1
602+ ci = cbin[idx]
603+ ts[ci] = vs[i]
604+ cbin[idx] -= 1
605+ end
606+ vs,ts = ts,vs
607+ swaps += 1
608+ end
609+
610+ if isodd (swaps)
611+ vs,ts = ts,vs
612+ for i = lo: hi
613+ vs[i] = ts[i]
614+ end
615+ end
616+ vs
617+ end
618+
619+ function Base. Sort. Float. fpsort! (v:: AbstractVector , :: RadixSortAlg , o:: Ordering )
620+ @static if VERSION >= v " 1.7.0-DEV"
621+ lo, hi = Base. Sort. Float. specials2end! (v, RadixSort, o)
622+ else
623+ lo, hi = Base. Sort. Float. nans2end! (v, o)
624+ end
625+ sort! (v, lo, hi, RadixSort, o)
626+ end
627+ end
628+
622629end # module
0 commit comments