Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minmax and extrema #5275

Merged
merged 3 commits into from
Jan 2, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,35 @@ function maximum{T<:FloatingPoint}(A::AbstractArray{T})
v
end

# extrema

function extrema{T<:Real}(A::AbstractArray{T})
if isempty(A); error("argument must not be empty"); end
n = length(A)

# locate the first non NaN number
v = A[1]
i = 2
while v != v && i <= n
@inbounds v = A[i]
i += 1
end

vmin = v
vmax = v
while i <= n
@inbounds v = A[i]
if v > vmax
vmax = v
elseif v < vmin
vmin = v
end
i += 1
end

return (vmin, vmax)
end


## map over arrays ##

Expand Down
2 changes: 2 additions & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ export
cumprod,
cumsum,
cumsum_kbn,
extrema,
fill!,
fill,
find,
Expand Down Expand Up @@ -524,6 +525,7 @@ export
maximum,
min,
minimum,
minmax,
nans,
ndims,
nnz,
Expand Down
8 changes: 6 additions & 2 deletions base/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export sin, cos, tan, sinh, cosh, tanh, asin, acos, atan,
log, log2, log10, log1p, exponent, exp, exp2, exp10, expm1,
cbrt, sqrt, erf, erfc, erfcx, erfi, dawson,
ceil, floor, trunc, round, significand,
lgamma, hypot, gamma, lfact, max, min, ldexp, frexp,
lgamma, hypot, gamma, lfact, max, min, minmax, ldexp, frexp,
clamp, modf, ^, mod2pi,
airy, airyai, airyprime, airyaiprime, airybi, airybiprime,
besselj0, besselj1, besselj, bessely0, bessely1, bessely,
Expand All @@ -20,7 +20,7 @@ export sin, cos, tan, sinh, cosh, tanh, asin, acos, atan,

import Base: log, exp, sin, cos, tan, sinh, cosh, tanh, asin,
acos, atan, asinh, acosh, atanh, sqrt, log2, log10,
max, min, ceil, floor, trunc, round, ^, exp2, exp10
max, min, minmax, ceil, floor, trunc, round, ^, exp2, exp10

import Core.Intrinsics.nan_dom_err

Expand Down Expand Up @@ -347,6 +347,10 @@ max{T<:FloatingPoint}(x::T, y::T) = ifelse((y > x) | (x != x), y, x)
min{T<:FloatingPoint}(x::T, y::T) = ifelse((y < x) | (x != x), y, x)
@vectorize_2arg Real min

minmax{T<:FloatingPoint}(x::T, y::T) = x <= y ? (x, y) :
x > y ? (y, x) :
x == x ? (x, x) : (y, y)

function exponent(x::Float64)
if x==0 || !isfinite(x)
throw(DomainError())
Expand Down
3 changes: 3 additions & 0 deletions base/promotion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ cmp(x::Real, y::Real) = cmp(promote(x,y)...)

max(x::Real, y::Real) = max(promote(x,y)...)
min(x::Real, y::Real) = min(promote(x,y)...)
minmax(x::Real, y::Real) = minmax(promote(x, y)...)

## catch-alls to prevent infinite recursion when definitions are missing ##

Expand All @@ -200,3 +201,5 @@ no_op_err(name, T) = error(name," not defined for ",T)

max{T<:Real}(x::T, y::T) = ifelse(y < x, x, y)
min{T<:Real}(x::T, y::T) = ifelse(x < y, x, y)
minmax{T<:Real}(x::T, y::T) = x < y ? (x, y) : (y, x)

21 changes: 21 additions & 0 deletions base/reduce.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@ function minimum(itr)
return v
end

function extrema(itr)
s = start(itr)
if done(itr, s)
error("argument is empty")
end
(v, s) = next(itr, s)
vmin = v
vmax = v
while !done(itr, s)
(x, s) = next(itr, s)
if x == x
if x > vmax
vmax = x
elseif x < vmin
vmin = x
end
end
end
return (vmin, vmax)
end

function sum(itr)
s = start(itr)
if done(itr, s)
Expand Down
5 changes: 5 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -355,10 +355,15 @@ end

@test maximum([4, 3, 5, 2]) == 5
@test minimum([4, 3, 5, 2]) == 2
@test extrema([4, 3, 5, 2]) == (2, 5)

@test isnan(maximum([NaN]))
@test isnan(minimum([NaN]))
@test isequal(extrema([NaN]), (NaN, NaN))

@test maximum([4., 3., NaN, 5., 2.]) == 5.
@test minimum([4., 3., NaN, 5., 2.]) == 2.
@test extrema([4., 3., NaN, 5., 2.]) == (2., 5.)

@test any([true false; false false], 2) == [true false]'
@test any([true false; false false], 1) == [true false]
Expand Down
7 changes: 7 additions & 0 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@
@test 2. * 3. == 6.
@test min(1.0,1) == 1

@test minmax(5, 3) == (3, 5)
@test minmax(3., 5.) == (3., 5.)
@test minmax(5., 3.) == (3., 5.)
@test minmax(3., NaN) == (3., 3.)
@test minmax(NaN, 3.) == (3., 3.)
@test isequal(minmax(NaN, NaN), (NaN, NaN))

# lexing typemin(Int64)
@test (-9223372036854775808)^1 == -9223372036854775808
@test [1 -1 -9223372036854775808] == [1 -1 typemin(Int64)]
Expand Down