Finding the vertices of a hypercube

I defined a data structure to represent a hypercube. It is defined by the min and max bounds on each dimension.

struct HyperCube 
    min_bounds::Array{Float32}
    max_bounds::Array{Float32}
end

Now, I want to define a function that returns all the vertices.
In Python, I would have done:
return list(product(*zip(self.min_bounds, self.max_bounds)))

I am wondering what would be the most elegant way to do this in Julia.

Thanks for the response. It is missing the zip part. The Python implementation would return the below list for the example:

[(1, 2, 3),
 (1, 2, 6),
 (1, 5, 3),
 (1, 5, 6),
 (4, 2, 3),
 (4, 2, 6),
 (4, 5, 3),
 (4, 5, 6)]

Please note that, in HyperCube([1, 2, 3], [4, 5, 6]) , there are three dimensions. The cube covers [1,4] in the first dimension, [2,5] in the second dimension, and so on.

I was stuck for sometime on how to do the Python’s f(*args) in Julia and then figured out:

collect(Iterators.product(zip(box.min_bounds, box.max_bounds)...))

I hope this works.

Note that you want Vector not Array here. Otherwise it’s an abstract type since you don’t appreciate the number of dimensions.

2 Likes

Iterators.product returns multi-dimensional object. You can add vec to flatten it

julia> vec(collect(Iterators.product(zip(box.min_bounds, box.max_bounds)...)))
8-element Vector{Tuple{Float32, Float32, Float32}}:
 (1.0, 2.0, 3.0)
 (4.0, 2.0, 3.0)
 (1.0, 5.0, 3.0)
 (4.0, 5.0, 3.0)
 (1.0, 2.0, 6.0)
 (4.0, 2.0, 6.0)
 (1.0, 5.0, 6.0)
 (4.0, 5.0, 6.0)
4 Likes

If you are worried about performance, I would also strongly consider using SVector from StaticArrays.jl here, at least if you are in low (< 20) dimensions, and anywhere you are using low-dimensional vectors in a fixed number of dimensions. (e.g. HCubature.jl does something similar for hypercubes.)

4 Likes

Apologies.

1 Like

Did you mean to have the struct definition as below?

struct HyperCube
    min_bounds::Vector{Float32}
    max_bounds::Vector{Float32}
end
1 Like

Yes. Exactly. Vector{Float32} is an alias for Array{Float32,1}

2 Likes