Randomly generate signed permutation matrix in Julia?

112 Views Asked by At

In Julia, I would like to generate a matrix with exactly one nonzero entry in each row and column, where each of these nonzero entries has modulus one. Is there any way to this in Julia?

2

There are 2 best solutions below

0
Dan Getz On BEST ANSWER

The result matrix has only n nonzero entries, so it is going to be sparse. So it might as well be generated as a sparse matrix:

using SparseArrays, Random

randspermmat(n) = SparseMatrixCSC(n, n,
  collect(1:n+1), shuffle(1:n), (-1).^rand(Bool,n))

Example usage:

julia> randspermmat(5)
5×5 SparseMatrixCSC{Int64, Int64} with 5 stored entries:
  ⋅  ⋅  1   ⋅  ⋅
  ⋅  1  ⋅   ⋅  ⋅
  ⋅  ⋅  ⋅   ⋅  1
 -1  ⋅  ⋅   ⋅  ⋅
  ⋅  ⋅  ⋅  -1  ⋅

Storage-wise this is much better than a full matrix, and the generation speed is also better, the bigger the matrix is.

ADDITION: This is common enough to appear in another package LuxurySparse.jl with even simpler definition possible:

using LuxurySparse, Random

randspermmat_alt(n) =
  PermMatrix(shuffle(1:n),(-1).^rand(Bool,n))

This package is even more efficient and might warrant a look depending on optimization required. A link: LuxurySparse package doc

0
AboAmmar On

You can simply shuffle row indices and place (1,-1) randomly in each column based on the shuffled row index.

function bipolar(siz)
    m = n = siz
    A = zeros(Int,m,n)
    rowind = shuffle(1:m)
    for (j,i) in enumerate(rowind)
        A[i,j] = rand((-1,1))
    end
    A 
end

Example run:

bipolar(5)
5×5 Matrix{Int64}:
 0  0  1   0  0
 0  0  0   0  1
 0  0  0  -1  0
 1  0  0   0  0
 0  1  0   0  0