Expansions
MoreMaps.jl
supports automatic expansion of iterators, allowing for efficient combinatorial mapping.
Basic Expansion
The typical expansion of two inputs x
and y
is the Cartesian product Use Iterators.product(x, y)
:
julia
x = 1:3
y = 4:6
C = Chart(expansion = Iterators.product)
z = map(tuple, C, x, y)
3×3 Matrix{Tuple{Int64, Int64}}:
(1, 4) (1, 5) (1, 6)
(2, 4) (2, 5) (2, 6)
(3, 4) (3, 5) (3, 6)
Multi-dimensional Expansions
Works with any number of iterators:
julia
x = 1:2
y = 3:4
z = 5:6
C = Chart(expansion = Iterators.product)
result = map((a, b, c) -> a + b + c, C, x, y, z)
2×2×2 Array{Int64, 3}:
[:, :, 1] =
9 10
10 11
[:, :, 2] =
10 11
11 12
Custom Expansion Functions
You can provide any custom expansion functions f(iters...)
that return an iterator of tuples:
julia
# Custom expansion that zips instead of products
function zip_expansion(iters...)
return zip(iters...)
end
x = 1:5
y = 6:10
C = Chart(zip_expansion)
z = map(tuple, C, x, y)
5-element Vector{Tuple{Int64, Int64}}:
(1, 6)
(2, 7)
(3, 8)
(4, 9)
(5, 10)
Expansion with Nested Arrays
Expansions interact with leaf types:
julia
x = [[1, 2], [3, 4]]
y = [[5, 6], [7, 8]]
# Expand outer arrays
C_outer = Chart(leaf = MoreMaps.All, expansion = Iterators.product)
result_outer = map((a, b) -> length(a) + length(b), C_outer, x, y)
# Expand at leaf level
C_leaf = Chart(leaf = Vector{Int}, expansion = Iterators.product)
result_leaf = map((a, b) -> a .+ b, C_leaf, x, y)
2×2 Matrix{Vector{Int64}}:
[6, 8] [8, 10]
[8, 10] [10, 12]
Practical Applications
Parameter Sweeps
julia
# Sweep over parameter combinations
alphas = [0.1, 0.5, 1.0]
betas = [1, 2, 3]
C = Chart(Threaded(), LogLogger(5), MoreMaps.All, Iterators.product)
results = map(C, alphas, betas) do α, β
# Simulate some computation
sum(α * sin(x) + β * cos(x) for x in 1:100)
end
3×3 Matrix{Float64}:
-0.545006 -1.07729 -1.60958
-0.595874 -1.12816 -1.66045
-0.65946 -1.19175 -1.72404
Grid Computations
julia
# Create a 2D grid evaluation
x_range = range(-1, 1, length=20)
y_range = range(-1, 1, length=20)
C = Chart(Threaded(), NoProgress(), MoreMaps.All, Iterators.product)
grid = map((x, y) -> x^2 + y^2, C, x_range, y_range)
20×20 Matrix{Float64}:
2.0 1.80055 1.62327 1.46814 … 1.62327 1.80055 2.0
1.80055 1.60111 1.42382 1.2687 1.42382 1.60111 1.80055
1.62327 1.42382 1.24654 1.09141 1.24654 1.42382 1.62327
1.46814 1.2687 1.09141 0.936288 1.09141 1.2687 1.46814
1.33518 1.13573 0.958449 0.803324 0.958449 1.13573 1.33518
1.22438 1.02493 0.847645 0.692521 … 0.847645 1.02493 1.22438
1.13573 0.936288 0.759003 0.603878 0.759003 0.936288 1.13573
1.06925 0.869806 0.692521 0.537396 0.692521 0.869806 1.06925
1.02493 0.825485 0.648199 0.493075 0.648199 0.825485 1.02493
1.00277 0.803324 0.626039 0.470914 0.626039 0.803324 1.00277
1.00277 0.803324 0.626039 0.470914 … 0.626039 0.803324 1.00277
1.02493 0.825485 0.648199 0.493075 0.648199 0.825485 1.02493
1.06925 0.869806 0.692521 0.537396 0.692521 0.869806 1.06925
1.13573 0.936288 0.759003 0.603878 0.759003 0.936288 1.13573
1.22438 1.02493 0.847645 0.692521 0.847645 1.02493 1.22438
1.33518 1.13573 0.958449 0.803324 … 0.958449 1.13573 1.33518
1.46814 1.2687 1.09141 0.936288 1.09141 1.2687 1.46814
1.62327 1.42382 1.24654 1.09141 1.24654 1.42382 1.62327
1.80055 1.60111 1.42382 1.2687 1.42382 1.60111 1.80055
2.0 1.80055 1.62327 1.46814 1.62327 1.80055 2.0
Dimension sweeps
Iterators.product
expansions work well with DimensionalData.jl
dimensions:
julia
using DimensionalData
x = X(1:3)
y = Y(4:6)
C = Chart(Iterators.product)
z = map(+, C, x, y)
┌ 3×3 DimArray{Int64, 2} ┐
├────────────────────────┴───────────────────────── dims ┐
↓ X Sampled{Int64} 1:3 ForwardOrdered Regular Points,
→ Y Sampled{Int64} 4:6 ForwardOrdered Regular Points
└────────────────────────────────────────────────────────┘
↓ → 4 5 6
1 5 6 7
2 6 7 8
3 7 8 9