Closed daanhb closed 3 years ago
It seems ApproxFun uses components
for this? @dlfivefifty
There could be a generic components
function, and a getcomponent(A, I...)
which defaults to getindex(components(A), I...)
. That may make a lot of getindex
machinery available.
I used component(A, I...)
for components(A)[I...]
though getcomponent
may also make sense. Given the very narrow use of get*
and set*
in Julia, see below autocomplete, I've always viewed getindex
and setindex
as an anachronism, but that's really just a personal preference.
julia> get
get getfield getkey
get! gethostname getpid
get_zero_subnormals getindex getproperty
julia> set
set_zero_subnormals setenv setprecision
setdiff setfield! setproperty!
setdiff! setindex! setrounding
Good point, I'd favour component
over getcomponent
because it is shorter... You don't typically spell out getindex
very often. I'm trying out a simple CompositeTypes.jl
package to implement this in general. It is worth doing well, because it could also contain a generic way of displaying composite structures (an implementation of show(io, object)
), which is a lot harder to do and @roelmatthysen had a very nice implementation technique for that.
See CompositeTypes.jl: the package defines iscomposite
, components
, ncomponents
, component(x, I...)
and (if applicable) setcomponent!(x, v, I...)
. Does that look like a plan?
The package also defines indexing and display, but that is opt-in only: using CompositeTypes.Indexing
and using CompositeTypes.Display
. For DomainSets.jl
, the display routines result in something like:
julia> boundary(UnitCube())
D₁ ∪ D₄ ∪ D₃
D₁ = D₂ × (0.0..1.0 (Unit)) × (0.0..1.0 (Unit))
D₂ = Point{Float64}(0.0) ∪ Point{Float64}(1.0)
D₃ = (0.0..1.0 (Unit)) × (0.0..1.0 (Unit)) × D₂
D₄ = (0.0..1.0 (Unit)) × D₂ × (0.0..1.0 (Unit))
This is used when a multi-line description of the object is possible. The shorter description in a single line is
julia> show(stdout, boundary(UnitCube()))
((Point{Float64}(0.0) ∪ Point{Float64}(1.0)) × (0.0..1.0 (Unit)) × (0.0..1.0 (Unit))) ∪ ((0.0..1.0 (Unit)) × (Point{Float64}(0.0) ∪ Point{Float64}(1.0)) × (0.0..1.0 (Unit))) ∪ ((0.0..1.0 (Unit)) × (0.0..1.0 (Unit)) × (Point{Float64}(0.0) ∪ Point{Float64}(1.0)))
This is not quite right yet, though closer to being correct than what is currently displayed. (Edited, I fixed the parentheses in the expression.)
Conclusion, for now I went with CompositeTypes
in v0.5. Any indexing one would like to do on composite domains can be done on components(domain)
instead.
Currently, composite structures in DomainSets are queried using
numelements
,elements(object)
andelements(object, i)
. This is done to avoid possible conflict with the use ofgetindex
for certain domains. The element functions are used in packages downstream, typically composite array-like objects, wheregetindex
does refer to the entries of the array and not to the list of composing objects.Still, this is a non-standard thing to do, and implementing
getindex
forUnionDomain
may not actually conflict with anything.On the other hand, a
UnionDomain
acts like a set of domains more than like an array, andSet
does not implementgetindex
because the ordering shouldn't matter. Also, in some cases, (like 2 .+ (0..1)), we think of domains like an infinite array of points, and perhaps that interpretation does lead to conflicts if some domains are an array of domains and others are not. Right now, the BroadcastStyle of a domain isDomainSetStyle
to support this.On the plus side, with the more standard
getindex
, it would probably become easier to manipulate composite domains with standard tools.