As long as we're giving methods that mimic the behavior, here is a quick implementation based on Kronecker's theorem.
RoUQ[u_] :=
If[! (Abs[N[u]] == 1), False,
If[! AlgebraicIntegerQ[u], False,
(f = MinimalPolynomial[u, x];
n = Exponent[f, x];
cf = CoefficientList[f, x]/Coefficient[f, x^n];
M = Table[
If[j == i + 1, 1,
If[i == n, -cf[[j]], 0]], {i, 1, n}, {j, 1, n}];
lambda = First[Eigenvalues[M, 1]];
Abs[N[lambda]] == 1)]]
The sole reason for building the matrix $M$ is that Eigenvalues[M,1]
is guaranteed to return the largest eigenvalue of $M$ (in absolute value), while I don't know how to tell FindRoot
that it must give me the largest root.
J.M. below suggests just finding all the roots and taking the largest one. Based on a tiny amount of testing, I think that this is slower. Here is what I did:
(* Both methods will be tested on the same set of polynomials *)
data=Table[Sum[RandomInteger[100] x^j, {j,0,10}], {i,1,10^4}];
(* Find all roots and extract the largest *)
BigRoot1[f_]:=Max[Abs[x] /. NSolve[f==0,x]]
(* Find the largest eigenvalue of the companion matrix. *)
BigRoot2[f_]:=
(n = Exponent[f, x];
cf = CoefficientList[f, x]/Coefficient[f, x^n];
M = Table[
If[j == i + 1, 1,
If[i == n, -cf[[j]], 0.0]], {i, 1, n}, {j, 1, n}];
lambda = First[Eigenvalues[M, 1]];
N[Abs[lambda]])
Timing[Map[BigRoot1, data]][[1]]
10.9893
Timing[Map[BigRoot2, data]][[1]]
3.00254
I wouldn't take these results too seriously, because I'm sure both implementations do the list processing inefficiently, but it suggests that I'm not crazy to use Eigenvalues[]
.