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?
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