-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Zeros #19635
Zeros #19635
Conversation
zs = zeros(SparseMatrixCSC([1 2; 3 4]), Complex{Float64}, (2,3)) | ||
test_zeros(zs, SparseMatrixCSC{Complex{Float64}}, (2, 3)) | ||
|
||
@test_throws Exception zeros(Float64, [1.]) #19265 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which exception type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This tests that the situation in #19265 throws an error. It is a method error, so one could test for method error explicitly. I thought about this, but I think the precise exception type is an implementation detail and does not need to be part of the spec?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should test specifically, otherwise a typo in the implementation could pass this test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point.
add a test for the situation from #19265 to make sure it doesn't alias now? |
I think this PR is ready. |
I think this could use a slightly better commit message. Would you mind squashing and adding a couple of lines? |
* Fix JuliaLang#19265. * Add methods to zeros, ones with analgous signature to similar.
Done. |
Needs a NEWS item. |
@@ -97,6 +97,8 @@ Library improvements | |||
That is, not every member of the input iterable will be visited if a `true` (in the case of `any`) or | |||
`false` (in the case of `all`) value is found, and `mapreduce` will visit all members of the iterable. | |||
|
|||
* Additional methods for `ones` and `zeros` functions. These have the same signature as the `similar` function. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Additional methods for `ones` and `zeros` functions to support the same signature as the `similar` function ([#19635]).
function ($fname)(a::AbstractArray, T::Type=eltype(a), dims::Tuple=size(a)) | ||
fill!(similar(a,T,dims), $felt(T)) | ||
end | ||
($fname)(T::Type, dims::Tuple) = ($fname)(Array{T}(dims...), T, dims) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't right: it allocates an Array{T}(dims...)
and passes it to $fname(...)
, but then that function calls similar
, which allocates an second array. So you end up allocating one more array than you need.
I think you just want
($fname)(T::Type, dims::Tuple) = fill!(Array{T}(dims...), $felt(T))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
($fname)(T::Type, dims::Tuple) = ($fname)(Array{T}(dims...), T, dims) | ||
($fname)(dims::Tuple) = ($fname)(Float64, dims) | ||
|
||
($fname)(a::AbstractArray,T::Type,dims::DimOrInd...) = ($fname)(a,T,dims) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DimOrInd
(an alias for Union{AbstractUnitRange{T},Integer}
) doesn't seem right here. Shouldn't it just be Integer...
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I stole this from similar
, which also uses DimOrInd
for some methods. I think DimOrInd
is for exotic things like OffsetArrays
?
@@ -564,9 +564,10 @@ julia> ones(Complex128, 2, 3) | |||
ones(t,dims) | |||
|
|||
""" | |||
ones(A) | |||
ones(A::AbstractArray, T=eltype(A)::Type, dims=size(A)::DimOrInd) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this type signature isn't right for dims
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right!
($fname)(T::Type, dims::Tuple) = fill!(Array{T}(dims...), $felt(T)) | ||
($fname)(dims::Tuple) = ($fname)(Float64, dims) | ||
|
||
($fname)(a::AbstractArray,T::Type,dims::DimOrInd...) = ($fname)(a,T,dims) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dims::Integer...
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I stole this from similar
, which also uses DimOrInd
for some methods. I think DimOrInd
is for exotic things like OffsetArrays
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay... abstractarray.jl calls to_shape(dims)
to get a tuple, though, and similar
also supports dims::NeedsShaping
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it would be better to just define:
$fname(a::AbstractArray, T::Type, dims::Tuple) = fill!(similar(a,T,dims), $felt(T))
$fname(a::AbstractArray, T::Type, dims...) = fill!(similar(a,T,dims...), $felt(T))
$fname(a::AbstractArray, T::Type=eltype(a)) = fill!(similar(a,T), $felt(T))
so that it can take any dims
argument supported by similar
and has the same behavior for exotic array types
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mhh okay, I was not aware of NeedsShaping
. I will think about a clean way to support this, if I don't find one, I will switch back to Integer
as you suggested in the beginning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The NeedsShaping
cases will be handled by the dims::Tuple
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
# exotic indexing | ||
oarr = zeros(randn(3), UInt16, 1:3, -1:0) | ||
@test indices(oarr) == (1:3, -1:0) | ||
test_zeros(oarr.parent, Matrix{UInt16}, (3, 2)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stevengj Here is a test that shows why ::DimOrInd
instead of ::Integers
was choosen.
$fname(a::AbstractArray, T::Type, dims...) = fill!(similar(a,T,dims...), $felt(T)) | ||
$fname(a::AbstractArray, T::Type=eltype(a)) = fill!(similar(a,T), $felt(T)) | ||
|
||
$fname(T::Type, dims::Tuple) = fill!(Array{T}(Dims(dims)...), $felt(T)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for splatting here; you can just do fill!(Array{T}(Dims(dims)), $felt(T))
I think?
@@ -564,9 +564,10 @@ julia> ones(Complex128, 2, 3) | |||
ones(t,dims) | |||
|
|||
""" | |||
ones(A) | |||
ones(A::AbstractArray, T=eltype(A)::Type, dims=size(A)::Tuple) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to document the dims...
case too. Is ones(T, dims...)
documented somewhere else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are at least some doctests where dims...
is used. I can be more explicit about it.
LGTM. |
Create an array of all ones of specified type. The type defaults to `Float64` if not specified. | ||
Create an array of all ones with the same layout as `A`, element type `T` and size `dims`. | ||
The `A` argument can be skipped, which behaves like `Array{Float64,0}()` was passed. | ||
For convenience `dims` may also be passed in variadic form. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"variadic form" is not very clear, we don't use that terminology anywhere else
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would you call it instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd spell out an example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe:
For convenience, `dims` may be passed as individual integer arguments, as in `zeros(3,4,5)`, rather than as a tuple.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are examples where dims...
is used already e.g. zeros(Int8, 2, 3)
. But I can open a new PR with stevengj's suggestion if you like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I think if we don't have a terminology for dims...
, we should introduce one. It occurs quite frequently and feels cumbersome not having a word for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think "variadic form" is fine, but it should be spelled out with an example as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without any explanation that's terribly jargony and not very clear
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then please make a PR that improves it.
JuliaLang#19635 merged two docstrings for each of `zeros` and `ones` in a single docstring each. This changes the signatures in the stdlib file to reflect that change.
JuliaLang#19635 merged two docstrings for each of `zeros` and `ones` in a single docstring each. This changes the signatures in the stdlib file to reflect that change.
Worth noting, the syntaxes |
Oh, looks like you test for this, but the true meaning is actually ambiguous unless the user supplies an intervening |
Good point! I think at the moment |
As long as the ambiguous case (not in the julia-method-sense, but in the "what do I mean?" sense) throws an error, we're probably OK. |
Seems like we need a depwarn. Julia 0.5: julia> ones(Float64, 1:5)
5-element Array{Float64,1}:
1.0
1.0
1.0
1.0
1.0 master: julia> ones(Float64, 1:5)
ERROR: MethodError: Cannot `convert` an object of type UnitRange{Int64} to an object of type Int64
This may have arisen from a call to the constructor Int64(...),
since type constructors fall back to convert methods.
Stacktrace:
[1] ones(::Type{T} where T, ::UnitRange{Int64}) at ./array.jl:252 |
Note that this depwarn should be viewed as a bugfix, and thus allowed even though we're in feature freeze. |
Bump @jw3126 (see the depwarn above). |
I can take care of the depwarn next weekend. |
Fix #19265 and add methods to
zeros
/ones
with same signature assimilar
.