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

[WIP] ProductedArrays #42

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

[WIP] ProductedArrays #42

wants to merge 1 commit into from

Conversation

johnnychen94
Copy link
Member

@johnnychen94 johnnychen94 commented Mar 15, 2021

This introduces an intermediate Cartesian product array type that can be used for many operations, depending on how we're going to reduce the item. I'll give two examples that motivate this PR.

In simple words, ProductedArrays is the array version of Iterators.product:

julia> a = Float64[0.1 0.2; 0.3 0.4]
2×2 Matrix{Float64}:
 0.1  0.2
 0.3  0.4

julia> b = [1 2; 3 4]
2×2 Matrix{Int64}:
 1  2
 3  4

julia> c = ProductedArray(a, b)
2×2×2×2 ProductedArray{Tuple{Float64, Int64}, 4, Tuple{Matrix{Float64}, Matrix{Int64}}}:
[:, :, 1, 1] =
 (0.1, 1)  (0.2, 1)
 (0.3, 1)  (0.4, 1)

[:, :, 2, 1] =
 (0.1, 3)  (0.2, 3)
 (0.3, 3)  (0.4, 3)

[:, :, 1, 2] =
 (0.1, 2)  (0.2, 2)
 (0.3, 2)  (0.4, 2)

[:, :, 2, 2] =
 (0.1, 4)  (0.2, 4)
 (0.3, 4)  (0.4, 4)

TODO:

  • performance tweak
  • tests and docs

Example: ReadonlyMultiMappedArray

a = Float64[0.1 0.2; 0.3 0.4]
b = [1 2; 3 4]

plusc_1 = mappedarray(+, a, b)

p = ProductedArray(a, b)
plusc_2 = mappedarray(i->reduce(+, p[i, i]), CartesianIndices(a))

plusc_1 == plusc_2 # true

Theoretically, we could build the *MultiMappedArray functionality on top of ProductedArray and thus simplify the implementation. To minimize the change, I might take a try but won't do it in this PR.

Example: pairwise/patch-wise distances

using Distances
A = [rand(Float64, 7, 7) for _ in 1:7];
B = [rand(Float64, 7, 7) for _ in 1:7];

patchwise_d1 = [euclidean(a, b) for a in A, b in B]

p = ProductedArray(A, B);
patchwise_d2 = mappedarray(x->reduce(euclidean, x), p)

patchwise_d1 == patchwise_d2 # true

@codecov
Copy link

codecov bot commented Mar 15, 2021

Codecov Report

Merging #42 (1c29d4a) into master (ca07b29) will decrease coverage by 4.75%.
The diff coverage is 0.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #42      +/-   ##
==========================================
- Coverage   82.78%   78.03%   -4.76%     
==========================================
  Files           1        2       +1     
  Lines         122      132      +10     
==========================================
+ Hits          101      103       +2     
- Misses         21       29       +8     
Impacted Files Coverage Δ
src/MappedArrays.jl 83.06% <ø> (+0.27%) ⬆️
src/ProductedArrays.jl 0.00% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ca07b29...1c29d4a. Read the comment docs.

@FelixBenning
Copy link

FelixBenning commented Jun 2, 2023

@johnnychen94 since this PR aged a bit - are you still interested in this project? I wasn't aware of this effort when I created https://github.com/lazyLibraries/ProductArrays.jl (its publishing is on hold: JuliaRegistries/General#84683) you seem to have thought about the "product of arrays" edge cases too - I have written some tests already but made no performance considerations. Maybe we could combine this effort?

EDIT: I would also be very willing to move the ProductArrays.jl project into the JuliaArrays group. This might potentially make more sense than doing this under mappedarrays where few will find them. It also allows for selective import.

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.

2 participants