-
-
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
broadcast
for AbstractArray
types
#17533
Comments
#17389 should fix this. |
No it doesn't? WARNING: Error during initialization of module Random:
Base.MethodError(f=Base.#promote_array_type(), args=(Base.#.+(), Array{UInt32, 1}[0x640c92bc, 0x07683af9, 0xe5e6e6d2, 0xb346b00e], 0x00000001))
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: http://docs.julialang.org
_ _ _| |_ __ _ | Type "?help" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.5.0-dev+12987 (2016-07-21 12:37 UTC)
_/ |\__'_|_|_|\__'_| | pz/pobc/70a6696 (fork: 2 commits, 0 days)
|__/ | x86_64-pc-linux-gnu
julia> immutable MyArray{T,N} <: AbstractArray{T,N}
a::Array{T,N}
end
julia> Base.linearindexing{T,N}(::Type{MyArray{T,N}}) = Base.LinearFast()
julia> Base.size(m::MyArray) = size(m.a)
julia> Base.getindex(m::MyArray, i::Int) = m.a[i]
julia> Base.setindex!(m::MyArray, v, i::Int) = m.a[i] = v
julia> Base.similar{T,N}(::MyArray, ::Type{T}, dims::NTuple{N,Int}) = MyArray(Array(T,dims))
julia> typeof(MyArray([1]).*MyArray([1]))
Array{Int64,1} |
@yuyichao You're right. I misred the OP. And I agree that this should use |
|
Don't we currently have |
I think it's inconsistent to make the output type depend on only the first of the arrays. Might need a |
I agree with what timholy says, but in fact it's what Julia does for binary operations. Try
To overcome this, you would probably have to introduce a new "promotion" system for |
@tkelman julia> a = MyArray(rand(4, 2))
4×2 MyArray{Float64,2}:
0.981792 0.116486
0.232802 0.519291
0.736532 0.234633
0.546964 0.80054
julia> map(x->x*2, a)
4×2 MyArray{Float64,2}:
1.96358 0.232972
0.465605 1.03858
1.47306 0.469265
1.09393 1.60108 I agree that basing the output type on the first arg seems weird. I've been thinking about a Then we could do something like: broadcast(f, As...) =
broadcast!(
f,
promote_similar(As, promote_eltype(As...), broadcast_shape(As...)),
As...
) Possibly
and then function broadcast(f, As...)
T = promote_type(map(typeof, As)...)
broadcast!(
f,
promote_similar(T, As, promote_eltype(As...), broadcast_shape(As...)),
As...
)
end Feels pretty fiddly. :/ I'm definitely interested in finding a solution though. I hit this trying to make sure I can do arithmetic on my |
With the current state of affairs, we have now (MyArray([1]) + [1])::Vector{1}
([1] + MyArray([1]))::Vector{1} that is, you now get an I believe that should solve this. |
If you want a specific container type for the output, you can also just use |
Given the number of operations that go through broadcast now, I don't think requiring in place operations to get these to return a specific array type is a good enough answer for extensibility. |
Also, maybe one wants to use the |
I've been thinking about this issue with respect to the broadcast revamp. Things are much improved since its inception given that we now have a documented interface for extending broadcast. It's still somewhat unsatisfactory, though, in that we don't yet have One possible solution would be for the fallback |
Consider the following code:
Thanks to the
AbstractArray
magic, these 8 lines should define a type with the same interface asArray
. This is however not the case:The problem originates from the following definition of
broadcast()
:I suggest changing this definition to:
This would fix the above problem.
The text was updated successfully, but these errors were encountered: