The following is a brute force approach to generate all matrices with the required structure. It is not recommended for use with "large" n
.
ClearAll[mF];
mF = With[{n = #, values = Join @@ Permutations /@ Subsets[Range[#2], {#3}],
positions = Join @@ (Tuples /@
Subsets[{#, Reverse@#} & /@ Subsets[Range[#], {2}], {#3}])},
SparseArray[#, {n, n}] & /@ (Rule @@@ Tuples[{positions, values}])] &;
Example 1: Changing your N
to n
, M
to q
, and m
to m
, all matrices for n=3, q=3, m=3
:
Grid@Partition[MatrixForm /@ Normal /@ mF2[3, 3, 3], 10]

Example 3: Five random matrices for n=5, q=4, m=3
Row[MatrixForm /@ Normal /@ RandomChoice[mF2[5, 4, 3], 5]]

How it works: using n=3; q=3; m=2
for illustration
Potential non-zero positions of the matrix are obtained using the following steps:
Get indices of above-diagonal positions:
Subsets[Range[n], {2}]
(* {{1, 2}, {1, 3}, {2, 3}} *)
Pair each position with its below-diagonal counterpart:
{#, Reverse@#} & /@ %
(* {{{1, 2}, {2, 1}}, {{1, 3}, {3, 1}}, {{2, 3}, {3, 2}}} *)
Get all m
subsets of these potential positions:
Subsets[%, {2}]
(* {{{{1, 2}, {2, 1}}, {{1, 3}, {3, 1}}},
{{{1, 2}, {2, 1}}, {{2, 3}, {3, 2}}},
{{{1, 3}, {3, 1}}, {{2, 3}, {3, 2}}}} *)
For each of the subsets above, form all tuples (picking one element from each sublist)
Tuples /@ %
(* {{{{1, 2}, {1, 3}}, {{1, 2}, {3, 1}}, {{2, 1}, {1, 3}}, {{2, 1}, {3, 1}}},
{{{1, 2}, {2, 3}}, {{1, 2}, {3, 2}}, {{2, 1}, {2, 3}}, {{2, 1}, {3, 2}}},
{{{1, 3}, {2, 3}}, {{1, 3}, {3, 2}}, {{3, 1}, {2, 3}}, {{3, 1}, {3, 2}}}} *)
Remove one level of nesting to get all potential non-zero positions:
positions =Join @@ %
(* {{{1, 2}, {1, 3}}, {{1, 2}, {3, 1}}, {{2, 1}, {1, 3}}, {{2, 1}, {3, 1}},
{{1, 2}, {2, 3}}, {{1, 2}, {3, 2}}, {{2, 1}, {2, 3}}, {{2, 1}, {3, 2}},
{{1, 3}, {2, 3}}, {{1, 3}, {3, 2}}, {{3, 1}, {2, 3}}, {{3, 1}, {3, 2}}} *)
To get the non-zero values to fill these non-zero positions, first find all m
-subsets of the set of integers Range[q]
:
Subsets[Range[q], {m}]
(* {{1, 2}, {1, 3}, {2, 3}} *)
Each set s
in the previous list can fill the m
positions Permutations[s]
ways:
Permutations /@ %
(* {{{1, 2}, {2, 1}}, {{1, 3}, {3, 1}}, {{2, 3}, {3, 2}}} *)
Remove one level of nesting to get all possible sets of non-zero values:
values = Join@@%
(* {{1, 2}, {2, 1}, {1, 3}, {3, 1}, {2, 3}, {3, 2}} *)
Form all pairs getting a set of non-zero positions from positions
and a set of non-zero values from values
:
Tuples[{positions, values}]
(* {{{{1,2},{1,3}},{1,2}},{{{1,2},{1,3}},{2,1}},{{{1,2},{1,3}},{1,3}},
... ,{{{3,1},{3,2}},{2,3}},{{{3,1},{3,2}},{3,2}}} *)
Associate the non-zero position set with non-zero value set using Rule
for each the sublists above:
Rule @@@ %
(* {{{1,2},{1,3}}->{1,2}, {{1,2},{1,3}}->{2,1}, {{1,2}, {1,3}}->{1,3},
... ,{{3,1},{3,2}}->{3,1}, {{3,1},{3,2}}->{2,3}, {{3,1},{3,2}}->{3,2}} *)
Use each element of the above list as the first argument of SparseArray
to form a matrix
SparseArray[#, {n, n}] & /@ %
(* {SparseArray[<2>,{3,3}],SparseArray[<2>,{3,3}], ...,
SparseArray[<2>,{3,3}],SparseArray[<2>,{3,3}]} *)
Organize for display using Normal
, MatrixForm
, Grid
:
Grid@Partition[MatrixForm /@ Normal /@ %, 10]
