matrixjulialinear-algebranumerical-methods

How to randomly generate a signed permutation matrix


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?


Solution

  • 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