Skip to content

Commit

Permalink
step 2 for #4235
Browse files Browse the repository at this point in the history
make minimum and maximum use scalarmin and scalarmax, which are min
  and max but exclude arrays

remove isless for AbstractArray

add LexicographicOrdering and use it in sortrows and sortcols
currently LexicographicOrdering is implemented with cmp(), which does
  the right thing for arrays, but we might not want to keep it that way
  • Loading branch information
JeffBezanson committed Oct 12, 2013
1 parent 85b440c commit 7d5f80c
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 53 deletions.
18 changes: 2 additions & 16 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -996,8 +996,6 @@ function cmp(A::AbstractArray, B::AbstractArray)
return cmp(nA, nB)
end

isless(A::AbstractArray, B::AbstractArray) = cmp(A,B)<0

function (==)(A::AbstractArray, B::AbstractArray)
if size(A) != size(B)
return false
Expand All @@ -1010,18 +1008,6 @@ function (==)(A::AbstractArray, B::AbstractArray)
return true
end

function (!=)(A::AbstractArray, B::AbstractArray)
if size(A) != size(B)
return true
end
for i = 1:length(A)
if A[i]!=B[i]
return true
end
end
return false
end

_cumsum_type{T<:Number}(v::AbstractArray{T}) = typeof(+zero(T))
_cumsum_type(v) = typeof(v[1]+v[1])

Expand Down Expand Up @@ -1395,9 +1381,9 @@ reducedim(f::Function, A, region, v0) =
reducedim(f, A, region, v0, similar(A, reduced_dims(A, region)))

maximum{T}(A::AbstractArray{T}, region) =
isempty(A) ? similar(A,reduced_dims0(A,region)) : reducedim(max,A,region,typemin(T))
isempty(A) ? similar(A,reduced_dims0(A,region)) : reducedim(scalarmax,A,region,typemin(T))
minimum{T}(A::AbstractArray{T}, region) =
isempty(A) ? similar(A,reduced_dims0(A,region)) : reducedim(min,A,region,typemax(T))
isempty(A) ? similar(A,reduced_dims0(A,region)) : reducedim(scalarmin,A,region,typemax(T))
sum{T}(A::AbstractArray{T}, region) = reducedim(+,A,region,zero(T))
prod{T}(A::AbstractArray{T}, region) = reducedim(*,A,region,one(T))

Expand Down
10 changes: 10 additions & 0 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ isless(x::Real, y::Real) = x<y
max(x,y) = y < x ? x : y
min(x,y) = x < y ? x : y

scalarmax(x,y) = max(x,y)
scalarmax(x::AbstractArray, y::AbstractArray) = error("max: ordering is not well-defined for arrays")
scalarmax(x , y::AbstractArray) = error("max: ordering is not well-defined for arrays")
scalarmax(x::AbstractArray, y ) = error("max: ordering is not well-defined for arrays")

scalarmin(x,y) = min(x,y)
scalarmin(x::AbstractArray, y::AbstractArray) = error("min: ordering is not well-defined for arrays")
scalarmin(x , y::AbstractArray) = error("min: ordering is not well-defined for arrays")
scalarmin(x::AbstractArray, y ) = error("min: ordering is not well-defined for arrays")

## definitions providing basic traits of arithmetic operators ##

+() = 0
Expand Down
10 changes: 7 additions & 3 deletions base/ordering.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ module Order
## notions of element ordering ##

export # not exported by Base
Ordering, Forward,
Ordering, Forward, Lexicographic,
By, Lt, Perm,
ReverseOrdering, ForwardOrdering,
ReverseOrdering, ForwardOrdering, LexicographicOrdering,
DirectOrdering,
lt, uint_mapping, ord, ordtype
# Reverse, # TODO: clashes with Reverse iterator
Expand All @@ -25,6 +25,9 @@ typealias DirectOrdering Union(ForwardOrdering,ReverseOrdering{ForwardOrdering})
const Forward = ForwardOrdering()
const Reverse = ReverseOrdering(Forward)

immutable LexicographicOrdering <: Ordering end
const Lexicographic = LexicographicOrdering()

immutable By <: Ordering
by::Function
end
Expand All @@ -43,6 +46,7 @@ lt(o::ForwardOrdering, a, b) = isless(a,b)
lt(o::ReverseOrdering, a, b) = lt(o.fwd,b,a)
lt(o::By, a, b) = isless(o.by(a),o.by(b))
lt(o::Lt, a, b) = o.lt(a,b)
lt(o::LexicographicOrdering, a, b) = cmp(a,b) < 0
lt(p::Perm, a, b) = lt(p.order, p.data[a], p.data[b])

# Map a bits-type to an unsigned int, maintaining sort order
Expand Down Expand Up @@ -78,7 +82,7 @@ ordtype (o::By, vs::AbstractArray) = try typeof(o.by(vs[1])) catc
ordtype{T}(o::Ordering, vs::AbstractArray{T}) = T

function ord(lt::Function, by::Function, rev::Bool, order::Ordering=Forward)
order == Forward ||
order == Forward || order == Lexicographic ||
Base.warn_once("the `order` keyword is deprecated, use `lt`, `by` and `rev` instead.")
o = (lt===isless) & (by===identity) ? order :
(lt===isless) & (by!==identity) ? By(by) :
Expand Down
28 changes: 8 additions & 20 deletions base/reduce.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
## reductions ##

function reduce(op::Function, itr) # this is a left fold
if is(op,max)
return maximum(itr)
elseif is(op,min)
return minimum(itr)
elseif is(op,+)
if is(op,+)
return sum(itr)
elseif is(op,*)
return prod(itr)
Expand Down Expand Up @@ -34,7 +30,7 @@ function maximum(itr)
(v, s) = next(itr, s)
while !done(itr, s)
(x, s) = next(itr, s)
v = max(v,x)
v = scalarmax(v,x)
end
return v
end
Expand All @@ -47,7 +43,7 @@ function minimum(itr)
(v, s) = next(itr, s)
while !done(itr, s)
(x, s) = next(itr, s)
v = min(v,x)
v = scalarmin(v,x)
end
return v
end
Expand Down Expand Up @@ -80,15 +76,7 @@ end

function reduce(op::Function, v0, itr)
v = v0
if is(op,max)
for x in itr
v = max(v,x)
end
elseif is(op,min)
for x in itr
v = min(v,x)
end
elseif is(op,+)
if is(op,+)
for x in itr
v = v+x
end
Expand Down Expand Up @@ -192,10 +180,10 @@ function all(itr)
return true
end

maximum(f::Function, itr) = mapreduce(f, max, itr)
minimum(f::Function, itr) = mapreduce(f, min, itr)
sum(f::Function, itr) = mapreduce(f, + , itr)
prod(f::Function, itr) = mapreduce(f, * , itr)
maximum(f::Function, itr) = mapreduce(f, scalarmax, itr)
minimum(f::Function, itr) = mapreduce(f, scalarmin, itr)
sum(f::Function, itr) = mapreduce(f, + , itr)
prod(f::Function, itr) = mapreduce(f, * , itr)

function count(pred::Function, itr)
s = 0
Expand Down
4 changes: 2 additions & 2 deletions base/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -333,14 +333,14 @@ sort(A::AbstractArray, dim::Integer; kws...) = mapslices(a->sort(a; kws...), A,
function sortrows(A::AbstractMatrix; kws...)
c = 1:size(A,2)
rows = [ sub(A,i,c) for i=1:size(A,1) ]
p = sortperm(rows; kws...)
p = sortperm(rows; kws..., order=Lexicographic)
A[p,:]
end

function sortcols(A::AbstractMatrix; kws...)
r = 1:size(A,1)
cols = [ sub(A,r,i) for i=1:size(A,2) ]
p = sortperm(cols; kws...)
p = sortperm(cols; kws..., order=Lexicographic)
A[:,p]
end

Expand Down
8 changes: 4 additions & 4 deletions base/sparse/sparsematrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -582,14 +582,14 @@ function reducedim{Tv,Ti}(f::Function, A::SparseMatrixCSC{Tv,Ti}, region, v0)
end

maximum{T}(A::SparseMatrixCSC{T}) =
isempty(A) ? error("maximum: argument is empty") : reducedim(max,A,(1,2),typemin(T))
isempty(A) ? error("maximum: argument is empty") : reducedim(scalarmax,A,(1,2),typemin(T))
maximum{T}(A::SparseMatrixCSC{T}, region) =
isempty(A) ? similar(A, reduced_dims0(A,region)) : reducedim(max,A,region,typemin(T))
isempty(A) ? similar(A, reduced_dims0(A,region)) : reducedim(scalarmax,A,region,typemin(T))

minimum{T}(A::SparseMatrixCSC{T}) =
isempty(A) ? error("minimum: argument is empty") : reducedim(min,A,(1,2),typemax(T))
isempty(A) ? error("minimum: argument is empty") : reducedim(scalarmin,A,(1,2),typemax(T))
minimum{T}(A::SparseMatrixCSC{T}, region) =
isempty(A) ? similar(A, reduced_dims0(A,region)) : reducedim(min,A,region,typemax(T))
isempty(A) ? similar(A, reduced_dims0(A,region)) : reducedim(scalarmin,A,region,typemax(T))

sum{T}(A::SparseMatrixCSC{T}) = reducedim(+,A,(1,2),zero(T))
sum{T}(A::SparseMatrixCSC{T}, region) = reducedim(+,A,region,zero(T))
Expand Down
16 changes: 8 additions & 8 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -645,20 +645,20 @@ begin
local a = rand(3,3)

asr = sortrows(a)
@test isless(asr[1,:],asr[2,:])
@test isless(asr[2,:],asr[3,:])
@test cmp(asr[1,:],asr[2,:])<0
@test cmp(asr[2,:],asr[3,:])<0

asc = sortcols(a)
@test isless(asc[:,1],asc[:,2])
@test isless(asc[:,2],asc[:,3])
@test cmp(asc[:,1],asc[:,2])<0
@test cmp(asc[:,2],asc[:,3])<0

asr = sortrows(a, rev=true)
@test isless(asr[2,:],asr[1,:])
@test isless(asr[3,:],asr[2,:])
@test cmp(asr[2,:],asr[1,:])<0
@test cmp(asr[3,:],asr[2,:])<0

asc = sortcols(a, rev=true)
@test isless(asc[:,2],asc[:,1])
@test isless(asc[:,3],asc[:,2])
@test cmp(asc[:,2],asc[:,1])<0
@test cmp(asc[:,3],asc[:,2])<0

as = sort(a, 1)
@test issorted(as[:,1])
Expand Down

0 comments on commit 7d5f80c

Please sign in to comment.