# How do I speed up Plot when the independent variable is in the Numerical expression

In the following

HH = H /. {μ -> 1, Δ -> .3, L -> 11, ky -> 0};
Plot[Re[Sort[Eigenvalues[HH]]], {kx, -2 π/11, 2 π/11}, PlotPoints -> 10]


where H is a matrix expression that depends on kx, ky, μ, L, Δ.

Is there a faster way to plot the numerical eigenvalues of this matrix as a function of kx, for example? Any help would be really appreciated.

Update

I'd like to state, I want to do this purely numerical. My issue is that I want to solve the eigenvalue problem for MANY values of kx. H can be large in this case, sometimes 400 by 400. I only used 10 PlotPoints just as an example. I found that Table is very quick and I can do a ListLinePlot. I just naively thought this same operation would be done in Plot. This is where my confusion still lies if someone wants to help :)

Second Update

Here is H as requested.

NN = 40;
MM = 2 NN + 1;
kM = Table[
Boole[m == n] (ky + I (kx + m 2 π/L)),
{m, -NN, NN, 1}, {n, -NN, NN, 1}];

kM2 = Table[
Boole[m == n] (ky - I (kx + m 2 π/L)),
{m, -NN, NN, 1}, {n, -NN, NN, 1}];

μM = IdentityMatrix[MM] μ;

ΔM = (Δ I/2 )
* Table[ (KroneckerDelta[m, n - 1] - KroneckerDelta[m, n + 1]),
{m, -NN, NN, 1}, {n, -NN, NN, 1}];

H = ArrayFlatten[{
{-μM, kM,0 μM, ΔM},
{kM2, -μM, -ΔM, 0 μM},
{0 μM, -ΔM, μM, kM2},
{ΔM, 0 μM, kM, μM}
}];


Third update
This is initially represented as $h= \vec{\sigma} \cdot \vec{k}-\mu$

$h_\tau= \vec{\sigma^{\ast}} \cdot \vec{k}+\mu$

$H=\left(\begin{array}{cc} h & i \Delta \sigma_y\\ -i \Delta\sigma_y & h_\tau \end{array}\right)$

where $\sigma$ are the Pauli matrices. The individual values change do to some implications from a physical system. I didn't want to get too deep into the physics, as there is another stack for that.

The block elements don't commute because the Pauli matrices don't commute, but if you see any symmetries that I don't see please do enlighten me. So far I've always done this numerically.

• @R.M Thank you for cleaning this up for me. I'm still trying to get the hang of this. Mar 13, 2012 at 21:59
• Does your matrix possess any special symmetries, such as is it Hermitian? Mar 15, 2012 at 16:16
• @rcollyer It is Hermitian. Mar 15, 2012 at 16:19
• Thanks. Then, kM == ConjugateTranspose[kM2], so you can simplify your code by eliminating kM2, and replace it with kM\[ConjugateTranspose]. And, as I pointed out before, you can replace the 0 \[Mu]M terms with 0, and it will be interpreted correctly. Any other symmetries that your aware of? If so, you can block-diagonalize it based upon those. Mar 15, 2012 at 16:32
• Here's a reference for the block-diagonalization. Mar 15, 2012 at 16:32

You are solving the eigenvalue problem for every point in the plot. If it is feasible to work out the analytical expression for the eigenvalues with kx as a symbol, then calculate that outside the plot and plot the solution.

HH = H /. {μ -> 1, Δ -> .3, L -> 11, ky -> 0};
eHH=Eigenvalues[HH]]];
Plot[Re[Sort[eHH]], {kx, -2 π/11, 2 π/11}, PlotPoints -> 10]


You could also try

Plot[Re[Sort[Evaluate@Eigenvalues[HH]]], {kx, -2 π/11, 2 π/11}, PlotPoints -> 10]


But seriously, if you only want ten plot points, precalculate the eigenvalues and then use ListPlot or ListLinePlot.

eHHlist= With[{HH = H /. {μ -> 1, Δ -> .3, L -> 11, ky -> 0}},
Table[Re[Sort[Eigenvalues[HH]]], {kx, -2 π/11, 2 π/11, 2  π/55}]  ]
ListPlot[eHHlist]

• Evaluate won't have any effect in that position. It only does something when you have Plot[Evaluate[...], ...]. Mar 14, 2012 at 4:39

Without seeing H, it's a little difficult to give the best answer, but I think calculating the eigenvalues numerically might speed things up considerably.

My guess is that the eigenvalues get computed symbolically, or at least Mathematica attempts it. Depending on the matrix, this can produce huge expressions. This is because Eigenvalues[HH] is evaluated before setting a value for kx. This would also prevent Sort from sorting by actual numerical values.

So, I recommend that you define a function like this:

Clear[hh]
hh[kx_?NumericQ] := Re@Eigenvalues[ (* paste HH here *) ]


and plot using

Plot[hh[kx], {kx, -2 π/11, 2 π/11}]


This should be very fast. But I can't know for sure that this is the best solution without seeing H first.

To avoid pasting by hand, you can do the following instead:

Clear[HH, hh]

HH[kx_] = H /. {μ -> 1, Δ -> .3, L -> 11, ky -> 0}

hh[kx_?NumericQ] := Re@Eigenvalues[HH[kx]]


Note my use of = and :=. The distinction is important.