2

I have a large matrix, say En En, as a function of two variables x and y which has En eigenvalues. I want to use ContourPlot to show specific eigenvalue, say (En/2)+1 with respect to x and y. For small En this can be done but it did not work for large En. For example, with En=8 it gives the desired result, but for larger En not working.

M1={{0, I Sin[x] + Sin[y], 3 - Cos[x] - Cos[y], -1}, {-I Sin[x] + Sin[y],
   0, -1, 3 - Cos[x] - Cos[y]}, {3 - Cos[x] - Cos[y], -1, 
  0, -I Sin[x] - Sin[y]}, {-1, 3 - Cos[x] - Cos[y], I Sin[x] - Sin[y],
   0}};

tc={{0, 0, 0, 0}, {0, 0, 0, 0}, {-1, 0, 0, 0}, {0, -1, 0, 0}};

Mn[n_] := 
 SparseArray[{Band[{1, 1}, {4 n, 4 n}] -> {M1}, 
   Band[{1, 5}, {4 n, 4 n}] -> {tc}, 
   Band[{5, 1}, {4 n, 4 n}] -> {ConjugateTranspose[tc]}}]

 w = 2; En = 4 w;(*w must be >1*)
ContourPlot[
 Evaluate[Eigenvalues[N@Mn[w]][[En/2 + 1]] == 0.4], {x, -2, 
  2}, {y, -2, 2}, ContourShading -> None, ContourStyle -> Blue]

this is the result with w=2 (i.e En=8) How can I do the same for w=40 (En=160)?

enter image description here

I try w=3 and got this error "Eigenvalues::eival: Unable to find all roots of the characteristic polynomial." and this is the final output:

enter image description here

MMA13
  • 4,664
  • 3
  • 15
  • 21
  • What specific problem do you observe with w=40? (Does it give a blank graph, an error message,...) – mikado Mar 30 '20 at 13:51
  • it gives error: Eigenvalues::eival: Unable to find all roots of the characteristic polynomial. and then the output is messy. I updated the question with w=3. – MMA13 Mar 30 '20 at 14:00

1 Answers1

1

There is no need to calculate the eigenvalues explicitly; it is enough to check that the characteristic polynomial has a zero. If you calculate the determinant numerically for specific numerical values of $x$, $y$, and the eigenvalue, then the characteristic polynomial can be circumvented and more stable algorithms can be applied:

MM[x_, y_] = Mn[w];
f[λ_?NumericQ, {x_?NumericQ, y_?NumericQ}] := 
  Det[MM[x, y] - λ*IdentityMatrix[En]]

With[{λ = 0.4}, 
  ContourPlot[f[λ, {x, y}] == 0, {x, -2, 2}, {y, -2, 2}]]

enter image description here

Alternatively, use the trick of this solution: for given $(x,y)$, calculate the eigenvalue that is closest to $\lambda$ by using a shifted Arnoldi-Lanczos iteration, and then contour-plot the difference between this eigenvalue and $\lambda$. This method is much faster and much more stable, but generates spurious contours whenever there's a switch from one eigenvalue branch to another:

g[λ_?NumericQ, {x_?NumericQ, y_?NumericQ}] := 
  Eigenvalues[MM[x, y], 1, 
              Method -> {"Arnoldi", "Criteria" -> "Magnitude", 
                         "Shift" -> λ}][[1]] - λ

With[{λ = 0.4}, 
  ContourPlot[g[λ, {x, y}] == 0, {x, -2, 2}, {y, -2, 2}]]

enter image description here

Roman
  • 47,322
  • 2
  • 55
  • 121
  • Wow,this is perfect, thanks! Is there a way to smooth the results? – MMA13 Mar 30 '20 at 20:44
  • @HD2006 see my update for a different, smoother algorithm. Also, the PlotPoints option can help. – Roman Mar 31 '20 at 09:13
  • I still need your help with one more thing that will be a great help. Can I get the values of {x, y} coincide with each contour? I really need this, may you please help me? – MMA13 Apr 11 '20 at 19:16
  • I suggest you ask a fresh question for this issue. – Roman Apr 11 '20 at 19:19