Skip to content

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