# How to plot the eigenvalues of a parametric matrix efficiently?

I was wondering how can I set the variable type of matrix elements to be real. The problem is, I creat a variable-dependent matrix as follows and I get the eigenvalues now I want to plot the functions above. The trouble is it cost a lot of time, and I don't know how to Compile such a set of function. So my problem is that how can I set the variable type at the very first or use the "Compile" to set the set of eigenvalues to be real-number valued? My code is listed in the following

L = 4;
H[t_] := SparseArray[
Flatten[
{
Table[{2 j - 1, 2 j} -> t, {j, 1, L}],
Table[{2 j, 2 j - 1} -> t, {j, 1, L}],
Table[{2 j, 2 j + 1} -> 1.0, {j, 1, L - 1}],
Table[{2 j + 1, 2 j} -> 1.0, {j, 1, L - 1}]
}
]
];
H[t] // MatrixForm
ev = Eigenvalues[H[t]]
Plot[ev, {t, -3.0, 3.0}]


Update: Thank @Henrik Schumacher@Roman very much.

Something went wrong when I applied it to an asymmetric matrix.

L=40;
H[t_]:= SparseArray[
Flatten[
{
Table[{2 j - 1, 2 j} -> t-2/3, {j, 1, L}],
Table[{2 j, 2 j - 1} -> t+2/3, {j, 1, L}],
Table[{2 j, 2 j + 1} -> 1.0, {j, 1, L - 1}],
Table[{2 j + 1, 2 j} -> 1.0, {j, 1, L - 1}]
}
]
];
H[t] // MatrixForm


Such a matrix have complex eigenvalues. And I will polt their real parts and imaginary parts separately.

f[t_?NumericQ]:= Re[Eigenvalues[H[N[t]]]]
Plot[Sort[f[t]], {t,-3.0,3.0}] // AbsoluteTiming


It took me about 5min, and here's the result

The left part is quite regular but the right part in the red box is not as smooth as that of the left part. And I wonder what's wrong?

• I don't get what the problem is. Even with real t, the eigenvalues are roots of a polynomial of degree 8. There is just no general closed-form expression for polynomials of degree greater than 5. – Henrik Schumacher May 19 '19 at 13:17
• I don't understand. Running your code (and generating the plot) takes about 3 seconds. Why is this a problem? – bill s May 19 '19 at 17:49
• Hello@bill s^_^,I take L=4 as an example. In fact I will deal with L=40 or even larger, and plot the eigenvalues as functions of the parameter t. At that time such a procedure is time - consuming. – Alex B May 20 '19 at 1:43
• Try increasing PlotPoints to make it smoother – SPPearce May 20 '19 at 5:44
• Hello@KraZug，thx for ur comment. It seems that 'plotpoints' is not the case, for a comparision the left part at the same place, is quite good. – Alex B May 20 '19 at 7:44

Maybe this helps? It shifts the computation to efficient eigenvalue computations in machine precision. The plot needs only 0.15 seconds on my machine.

f[t_?NumericQ] := Eigenvalues[H[N[t]]];
Plot[Sort[f[t]], {t, -3.0, 3.0}]


# Edit

As it turns out, you are lucky: For the characteristic polynomial of H[t] is a polynomial of order $$L$$ order in $$t^2$$. Thus, it can be solved explicitly for $$L \leq 4$$ and the result can be compiled:

H[t_, L_] := With[{a = Most[Join @@ ConstantArray[{t, 1}, L]]},
SparseArray[{
Band[{1, 2}] -> a,
Band[{2, 1}] -> a
},
{2 L, 2 L}, 0
]
];
L =4;
cλ = With[{
code = N[λ /.mSolve[Det[H[t, L] - λ IdentityMatrix[2 L]] == 0, λ]]
},
Compile[{{t, _Complex}},
Re@code,
CompilationTarget -> "WVM",
RuntimeAttributes -> {Listable},
Parallelization -> True
]
];

a = -3.;
b = 3.;
ListLinePlot[
Transpose[cλ[Subdivide[a, b, 1000]]],
DataRange -> {a, b}
] However, this is limited to the case $$L \leq 4$$.

• Hello @Henrik Schumacher, I would like to thank you for your helpful advice very much. You have perfectly solved my problem. The reason why I would set the variable type to be real is that from my limited knowledge it would remarkably speed up the ploting of functions. I am a beginner of MMA and your method is fantastic, and I'm looking forward to learning form such expert as you in the future. – Alex B May 19 '19 at 13:33
• You are flattering me. Anyways, you're welcome. – Henrik Schumacher May 19 '19 at 13:53
• f[t_?NumericQ] := Eigenvalues[H[N[t]]] for a speedup even if t is given as an infinite-precision object. – Roman May 19 '19 at 14:57
• @Roman Good point. I relied on the fact that Plot supplies f only with machine precision numbers. – Henrik Schumacher May 19 '19 at 14:59