-
-
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
Broadcasting with Set returns an arbitrarily-ordered array #33282
Comments
I’m in favour of adding a As a counterpoint, we sort of already have this with adjoints in the sense if z in f.(x,y’) if and only if |
I would still treat this a join combined with a special treatment (= broadcasting) of a singleton axis. I added "(and special handling for singleton axes)" in the OP to clarify my point. |
If we were to use set arithmetic for broadcasting with sets, I'd argue we should forbid mixing it with arrays. It may be tempting to "promote" arrays or any iterators as sets. However, it would produce different results depending on how you associate operators. For example, in x :: Set
y :: Vector
z :: Vector
a = x .+ y .+ z # equivalent to (x .+ y) .+ z
b = x .+ identity(y .+ z)
|
I would propose the following:
julia> x = Set([1,2,3])
Set([2, 3, 1])
julia> exp.(x) # Should return `Set([exp(2),exp(3),exp(1)])`
3-element Array{Float64,1}:
7.38905609893065
20.085536923187668
2.718281828459045
So the rough implementation would be: struct SetStyle <: BroadcastStyle end
BroadcastStyle(::Type{<:AbstractSet}) = SetStyle()
BroadcastStyle(::SetStyle, ::DefaultArrayStyle{0}) = SetStyle()
BroadcastStyle(::SetStyle, ::SetStyle) =error("Cannot broadcast sets together")
BroadcastStyle(::SetStyle, ::AbstractArrayStyle) = error("Cannot broadcast sets and arrays")
copy(b::Broadcast{SetStyle}) = Set(broadcast(b.f, collect.(b.args))) |
If we really want to argue that
which would essentially be equivalent to set functions. But I think that may be pushing things.... |
@nalimilan Thank you. Reviving #28491 seems to be the easiest short-term option. |
The decision to deprecate Based on those issues and PRs however the current behaviour is desired. Unfortunately its not very compatible with uncountable sets a la IntervalSets.jl , and its not clear what the analogue of |
@dlfivefifty I'm thinking that we don't have to follow the current definition strictly if there is a way to generalize the definition to have useful broadcasting with sets. Taking product is certainly useful and probably OK provided that mixing sets with arrays and dicts is an error but I'd be interested in what others think about this. |
I suppose the issue is that there is a desire for |
It's not defined, but it is meaningful, and so it's not "broken". For example, here's a fairly useless one-liner for doing random things to the values in a dictionary by iterating 3 sets:
This also doesn't consider OrderedSet, where the order is defined.
This is what |
@vtjnash I think your observation is that current broadcasting definition is useful when the order has some meaning as in the case of |
I agree with @tkf. Broadcasting should only work between ordered collections (including More broadly, it might be good to sort out what
So broadcasting is well-defined for shaped sets. If we assume unshaped ordered sets default to "vector-like", then we can extend the definition for any ordered sets. This leaves sets which are not ordered ( Edit: forgot a key one: \6. A uniquely enumerable set is an enumerable set where each element appears exactly once. This includes |
I think definition 6 is closer to sets in math although they doesn't have to be enumerable. Definition 1 seems to be closer to what is called multiset or bag. Definition 4 seems to be equivalent to what it's called associative data structure. But I guess you are trying to formalize the capabilities of containers? By maybe using traits? For example does adding
I think I agree. But as a brainstorming, I think one possibility is to use:
But this probably is "too dynamic" for people reading the code. I wish there was a generic customizable lifting syntax... (see also Status of question mark syntax for missing values - Development - JuliaLang) |
This is definitely not true (see Wikipedia). Definition 1 is the closest, in that a set only has the operation struct LazyUnion
a
b
end
in(x, d::LazyUnion) = x in d.a || x in d.b Therefore LazyUnion satisfies Definition 1 provided (The axiom of choice comes into play whether there is also a "choice" function but that's off topic.)
Agreed, though I would argue that its well-defined and consistent provided there is only one one set. Actually, I'd be happy if base just throws a "method not found" and then there could be another package SetBroadcasting.jl that implements a |
Hmm... it still sounds problematic to me because, if an object has more properties than set, it can distinguish itself from the other by using such properties (ordering, multiplicity, etc.). For example, if you treat an |
I agree that this is nice to have. But I prefer to do this without type-piracy, for example, using syntax like setstyle.(set1 .+ set2) where Note that this requires us to use an approach different from #28491 which uses |
Bump. I would like to rekindle the discussion here. I recently had a bug related to this issue. |
is there objection to this? I don't think the current behavior is reliable so hopefully no code relies on the behavior (need PkgEval in any case) |
I'd be fine with things like |
Currently (Julia 1.4-DEV), broadcasting with Set produces a result that relies on iteration order of
Set
which is not meaningful:This is due to the fallback to
collect
inbroadcastable
definition:julia/base/broadcast.jl
Line 664 in 9a8b2fd
A sensible definition may be to use set arithmetic (ref: JuliaMath/IntervalSets.jl#55) such that, for example,
holds. However, given that "join" on indices/keys is proposed as a generalized form of broadcasting #25904 (and special handling for singleton axes), it is not clear how taking "product" for broadcasting with
Set
s can fit in a bigger picture.So, as a short-term solution, I propose to forbid broadcasting with
Set
s which can easily be done by definingbroadcastable(::AbstractSet)
, as done withDict
s:julia/base/broadcast.jl
Line 665 in 9a8b2fd
This, of course, requires core devs to decide that this can be treated as a "minor change."
As a longer-term solution, does it make sense to use set arithmetic (which, I suppose, implementable using the style mechanism)? Is there a guiding principle in which it is natural to have "product" for
Set
s and "join" for associative data structures (includingArray
s)?The text was updated successfully, but these errors were encountered: