Using similarity transformation
A similarity transformation does not change the eigenvalues of a matrix, i.e. the matrix $A$ and $M^{-1} A M$ have the same eigenvalues.
Using this you can define a function
randomMatrixWithEigenvalues[eigenvalues_List] :=
Module[{n = Length[eigenvalues], a, m},
a = DiagonalMatrix@eigenvalues;
m = RandomInteger[{1, 10}, {n, n}];
While[Det[m] == 0, m = RandomInteger[{1, 10}, {n, n}];];
Inverse[m].a.m
]
which will in general give you a matrix over the rationals.
eigenvalues = {1, 2, -2};
Sort@eigenvalues ==
Sort@Eigenvalues@randomMatrixWithEigenvalues[eigenvalues]
(* True *)
Using FindInstance
You can also notice that per definition of eigenvalues the random matrix $X$ must satisfy
$$\mathrm{det}(X - \lambda I) = \prod_{i} (\lambda_i - \lambda)$$
and you can therefore also define
randomIntegerMatrixWithEigenvalues[eigenvalues_List] :=
Module[{n = Length[eigenvalues], x, \[Lambda], a},
x = Array[a, {n, n}];
x /. First@FindInstance[
And @@ (# == 0 & /@
CoefficientList[#, \[Lambda]] &@(Subtract @@ (Det[
x - \[Lambda] IdentityMatrix[n]] ==
Times @@ (# - \[Lambda] & /@ eigenvalues)))),
Flatten[{x}],
Integers
]
]
Then you can get a random matrix with integer coefficients
x = randomIntegerMatrixWithEigenvalues[eigenvalues]
(* {{3,2,-2},{-2,-1,-1},{-1,-1,-1}} *)
Sort@eigenvalues == Sort@Eigenvalues@x
(* True *)
Using HermiteDecomposition
This is adapted from J.M.'s answer to the question Generate “nice” random matrix
randomIntegerMatrixWithEigenvalues[eigenvalues_] :=
Module[{n = Length[eigenvalues], vm, jm},
vm = First[HermiteDecomposition[RandomInteger[{-1, 1}, {n, n}]]];
jm = SparseArray[
Band[{1,
1}] -> (If[Length[#] == 1, {#},
DiagonalMatrix[#] +
DiagonalMatrix[RandomInteger[1, Length[#] - 1], 1]] & /@
Split@Sort@eigenvalues)];
Inverse[vm].jm.vm
]