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

Deprecate vectorized clamp methods in favor of compact broadcast syntax #18609

Closed
wants to merge 1 commit into from
Closed
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
3 changes: 3 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1168,4 +1168,7 @@ for (dep, f, op) in [(:sumabs!, :sum!, :abs),
end
end

# Deprecate manually vectorized clamp methods in favor of compact broadcast syntax
@deprecate clamp(A::AbstractArray, lo, hi) clamp.(A, lo, hi)

# End deprecations scheduled for 0.6
11 changes: 2 additions & 9 deletions base/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ import Core.Intrinsics: sqrt_llvm, box, unbox, powi_llvm
clamp(x, lo, hi)

Return `x` if `lo <= x <= hi`. If `x < lo`, return `lo`. If `x > hi`, return `hi`. Arguments
are promoted to a common type. Operates elementwise over `x` if `x` is an array.
are promoted to a common type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this need a rerun of make docs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That it does! Good catch. Fixed. Thanks!


```jldoctest
julia> clamp([pi, 1.0, big(10.)], 2., 9.)
julia> clamp.([pi, 1.0, big(10.)], 2., 9.)
3-element Array{BigFloat,1}:
3.141592653589793238462643383279502884197169399375105820974944592307816406286198
2.000000000000000000000000000000000000000000000000000000000000000000000000000000
Expand All @@ -54,13 +54,6 @@ clamp{X,L,H}(x::X, lo::L, hi::H) =
convert(promote_type(X,L,H), lo),
convert(promote_type(X,L,H), x)))

clamp{T}(x::AbstractArray{T,1}, lo, hi) = [clamp(xx, lo, hi) for xx in x]
clamp{T}(x::AbstractArray{T,2}, lo, hi) =
[clamp(x[i,j], lo, hi) for i in indices(x,1), j in indices(x,2)]

clamp{T}(x::AbstractArray{T}, lo, hi) =
reshape([clamp(xx, lo, hi) for xx in x], size(x))

"""
clamp!(array::AbstractArray, lo, hi)

Expand Down
4 changes: 2 additions & 2 deletions test/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
@test clamp(3.0, 1, 3) == 3.0
@test clamp(4.0, 1, 3) == 3.0

@test clamp([0, 1, 2, 3, 4], 1.0, 3.0) == [1.0, 1.0, 2.0, 3.0, 3.0]
@test clamp([0 1; 2 3], 1.0, 3.0) == [1.0 1.0; 2.0 3.0]
@test clamp.([0, 1, 2, 3, 4], 1.0, 3.0) == [1.0, 1.0, 2.0, 3.0, 3.0]
@test clamp.([0 1; 2 3], 1.0, 3.0) == [1.0 1.0; 2.0 3.0]
begin
x = [0.0, 1.0, 2.0, 3.0, 4.0]
clamp!(x, 1, 3)
Expand Down
2 changes: 1 addition & 1 deletion test/offsetarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ seek(io, 0)
@test readdlm(io, eltype(A)) == parent(A)

amin, amax = extrema(parent(A))
@test clamp(A, (amax+amin)/2, amax) == clamp(parent(A), (amax+amin)/2, amax)
@test clamp.(A, (amax+amin)/2, amax).parent == clamp.(parent(A), (amax+amin)/2, amax)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this need .parent now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The operation on the left produces a TestHelpers.OAs.OffsetArray (from test/TestHelpers.jl) whereas that on the right produces an Array. Comparing an OffsetArray to an Array seems to fail even when their contents are identical, hence the .parent. Thoughts? Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and without broadcast what type did it return?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An OffsetArray ought not to be substituted for an Array. If broadcast is not preserving offsets, then that needs to be fixed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing vectorized clamp methods return an Array subtype independent of the input type (for example, clamping a SparseMatrixCSC or OffsetArray yields an Array). On the other hand broadcast better preserves the input type (for example, clamping a SparseMatrixCSC yields a SparseMatrixCSC and the analog holds for OffsetArrays). Thoughts? Thanks!

Copy link
Contributor

@TotalVerb TotalVerb Sep 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since clamp is not zero-preserving, I think the old behaviour for SparseMatrixCSC was preferred.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right, only zero-preserving if the bounds include the origin, but sometimes preserving structure wouldn't be type stable

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Tricky. Special case sparse and structured matrix types?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the broadcast code will now check if this is zero preserving right? and return dense-in-sparse-format if not?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should, yes. Best!


@test unique(A, 1) == parent(A)
@test unique(A, 2) == parent(A)
Expand Down