juliacombinatorics

Combinatorics variations, not combinations


I have 3x3 matrix, and its elements can have values -1, 0 or 1. I want to get all the possible variations, so the total number of results (all 3x3 matrices) should be 3^(3*3)=19683.

Example result: [[0,-1,-1],[-1,1,0],[0,0,1]]

I tried to use the combinatorics.jl package, but it's only for combinations, not variations.

I get that 19683 is a lot, but I'll later reduce the number based on some criteria.


Solution

  • The following function returns an iterator for the matrix variations as described in the OP:

    function variations(size, vals)
        n = prod(size)
        k = length(vals)
        idxs = CartesianIndices(ntuple(i->k, n))
        return Iterators.map(idxs) do x
            return reshape(getindex(vals, collect(Tuple(x))), size)
        end
    end
    

    The heavy lifting is done by CartesianIndices which returns an iterator going over all the possible indices of a tensor. A little massaging into the desired shape gives the answer.

    A smaller example than the OP can be:

    julia> variations((2,2),[-5,5]) |> collect |> vec
    16-element Vector{Matrix{Int64}}:
     [-5 -5; -5 -5]
     [5 -5; -5 -5]
     [-5 -5; 5 -5]
     [5 -5; 5 -5]
     [-5 5; -5 -5]
     [5 5; -5 -5]
     [-5 5; 5 -5]
     [5 5; 5 -5]
     [-5 -5; -5 5]
     [5 -5; -5 5]
     [-5 -5; 5 5]
     [5 -5; 5 5]
     [-5 5; -5 5]
     [5 5; -5 5]
     [-5 5; 5 5]
     [5 5; 5 5]
    

    The question asked for the following iterator:

    variations((3,3),[-1, 0, 1])