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

Product Array #49988

Closed
wants to merge 2 commits into from
Closed

Conversation

FelixBenning
Copy link

Spin-off from #49965. The goal is to enable users to do

julia> vec(PermutedDimsArray(Iterators.product(rand(3), 1:4), (2,1)))
12-element reshape(PermutedDimsArray(::Matrix{Tuple{Float64, Int64}}, (2, 1)), 12) with eltype Tuple{Float64, Int64}:
 (0.39059299961662275, 1)
 (0.39059299961662275, 2)
 (0.39059299961662275, 3)
 (0.39059299961662275, 4)
 (0.1864604429198029, 1)
 (0.1864604429198029, 2)
 (0.1864604429198029, 3)
 (0.1864604429198029, 4)
 (0.3248860864098778, 1)
 (0.3248860864098778, 2)
 (0.3248860864098778, 3)
 (0.3248860864098778, 4)

for this ProductIterator would need to be a subtype of AbstractArray, which it can not be in general. This Pull request introduces the ProductArray as a complement to the ProductIterator and uses traits to decide which to use when product is called. This decision might be possible to generalize further. Using a type union the existing implementations for ProductIterator are then all reused for ProductArray (only that it also inherits functionality from AbstractArray.

I am not very familiar with the internals of juila, so my usage of Unions might not be performance optimal.

The same idea could in principle also be applied to Flatten with the same goal.

@MasonProtter
Copy link
Contributor

I wonder if the best solution for this is to just use https://github.com/JuliaArrays/MappedArrays.jl instead of adding another iterator type to julia. E.g.

julia> using MappedArrays

julia> m_prod = let v1 = rand(3), v2= 1:4
           Is = CartesianIndices((axes(v1)..., axes(v2)...))
           mappedarray(I ->(v1[I[1]], v2[I[2]]), Is)
       end
3×4 mappedarray(var"#12#13"{Vector{Float64}, UnitRange{Int64}}([0.7870192228323807, 0.49428680787475354, 0.7833575043171959], 1:4), ::CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}) with eltype Tuple{Float64, Int64}:
 (0.787019, 1)  (0.787019, 2)  (0.787019, 3)  (0.787019, 4)
 (0.494287, 1)  (0.494287, 2)  (0.494287, 3)  (0.494287, 4)
 (0.783358, 1)  (0.783358, 2)  (0.783358, 3)  (0.783358, 4)

julia> vec(PermutedDimsArray(m_prod, (2,1)))
12-element reshape(PermutedDimsArray(mappedarray(var"#12#13"{Vector{Float64}, UnitRange{Int64}}([0.7870192228323807, 0.49428680787475354, 0.7833575043171959], 1:4), ::CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}), (2, 1)), 12) with eltype Tuple{Float64, Int64}:
 (0.7870192228323807, 1)
 (0.7870192228323807, 2)
 (0.7870192228323807, 3)
 (0.7870192228323807, 4)
 (0.49428680787475354, 1)
 (0.49428680787475354, 2)
 (0.49428680787475354, 3)
 (0.49428680787475354, 4)
 (0.7833575043171959, 1)
 (0.7833575043171959, 2)
 (0.7833575043171959, 3)
 (0.7833575043171959, 4)

@FelixBenning
Copy link
Author

The compiler neither likes

const Product{T} where {T<:Tuple} = Union{ProductIterator{T}, ProductArray{T}}

Nor likes

IteratorSize(::Type{PT{Tuple{}}}) where {PT<:Product} = HasShape{0}()

and I am too tired to find a solution right now.

@FelixBenning
Copy link
Author

@MasonProtter you are probably right about the mapped arrays being a good solution - you don't happen to know a good way to simplify the output? A wrapper would take away functionality so I want to avoid that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants