Random Matrices
The paper Setting linear algebra problems by John Steele (2003) provides interesting mathematical background.
STACK has a contributed library for creating structured random matrices. The code is online in the contributed library. To use this library you must load it into the question variables.
- To use the latest code from github:
stack_include_contrib("rand_matrix.mac");
Structured Random Matrices
rand_matrix.mac
includes a set of functions that will generate random matrices of a certain size and shape.
rand_matrix(m, n, k)
will generate an matrix with entries chosen from integers between and (inclusive).rand_diag(m, n, k)
will generate an diagonal matrix with diagonal entries chosen from integers between and (inclusive). All off-diagonal entries are set to zero.rand_triu(m, n, k)
will generate an upper triangular matrix with entries chosen from to (inclusive). All entries below the diagonal are set to zero.rand_tril(m, n, k)
will generate an lower triangular matrix with entries chosen from to (inclusive). All entries above the diagonal are set to zero.
Notes.
- You may omit the third argument,
k
, and STACK will assume . -
is an allowed value in all of the above cases, so you cannot guarantee properties like invertibility even with
rand_diag
. - For non-negative entries apply
abs
, e.g. useabs(rand_matrix(m, n, k))
.
The above functions have _list
and _list_no_replacement
varieties.
rand_matrix_list(m, n, L)
will generate an matrix with entries selected from provided listL
. Items inL
may appear more than once in the resulting matrix.rand_matrix_list_no_replacement(m, n, L)
will generate an matrix with entries selected from provided listL
. Items inL
will not appear more than once. IfL
is too short to fill the resulting matrix,matrix([null])
is returned instead.
You can also use rand_diag_list
, rand_triu_list
, rand_tril_list
, rand_diag_list_no_replacement
, rand_triu_list_no_replacement
and rand_tril_list_no_replacement
as expected.
Random Matrices with Certain Properties
rand_matrix.mac
also includes functions for matrices with useful properties. e.g. rand_invertible(n)
will generate an invertible matrix.
In many of these functions you can optionally add an extra input, k
, which can be read as a "level of complexity". It defaults to 1
. For example, rand_invertible(3)
might produce something like
whilst rand_invertible(3,5)
might produce something like .
rand_invertible(n, k)
will generate an integer invertible matrix.k
is the optional "level of complexity" and defaults to 1.rand_integer_invertible(n, k)
will generate an integer invertible matrix whose inverse is also an integer matrix.k
is the optional "level of complexity" and defaults to 1.rand_orth(n, k)
will generate an orthogonal matrix.k
is the optional "level of complexity" and defaults to 1.rand_orthcols(m, n, k)
will generate an matrix whose columns are an orthonormal set. Ifm
is less thann
, then it instead returnsmatrix([null])
.k
is the optional "level of complexity" and defaults to 1.rand_diagonalizable(n, k)
will generate an integer diagonalizable matrix.k
is the optional "level of complexity" and defaults to 1.k
determines both the level of complexity for eigenvalues and eigenvectors, so finer control can be achieved withD: rand_diag(...)
in conjunction withP: rand_integer_invertible(...)
and thenM: P . D . P^^-1
.rand_defective(n, k)
will generate an integer defective matrix.k
is the optional "level of complexity" and defaults to 1.k
determines both the level of complexity for eigenvalues and generalised eigenvectors.rand_perm_matrix(n)
will generate a random permutation matrix.
Under the hood, all of these functions with optional k
are produced by first multiplying two triangular matrices with non-zero diagonal entries. k
plays the same role in the generation of those matrices as it does in the similar function rand_triu
.
Some advice on the use of these functions
Careful use of deployed variants are key to success here. The "level of complexity" k
is quite volatile, and unexpectedly complicated or simple matrices can appear with some regularity. In general, the author believes it is better to err on the side of higher k
and then aggressively trim the variants.
Don't forget to check that intermediate steps of working are appopriate too! It's quite common in linear algebra to generate a problem that has "nice" numbers at the beginning and "nice" numbers in the final answer, but with some horrid working in the middle.
A good general principle is to work backwards from a solution. E.g. if you want to randomly generate a linear system with "nice" row-reduction steps, consider randomly generating elementary matrices and multiplying the answer by these. This ensures an answer with the desired properties (e..g unique integer solutions), finely controls the steps needed, and the intermediate working complexity.