The desired imaginary parts are represented by v
in algebraic formulation below. Put u
before v
in the variables for GroebnerBasis
to get the first polynomial to define v
in terms of x
and y
. Reverse (v
before u
, both before x, y
) to get the real part u
in terms of x
and y
.
branches = u + I v - Eigenvalues[H];
surf = Times @@ branches // Simplify;
parts = ReIm[surf] // ComplexExpand;
gb = GroebnerBasis[parts, {u, v, x, y}];
ContourPlot3D[
First[gb] == 0 // Evaluate, {x, 0, 2}, {y, -1, 1}, {v, -2, 2},
Mesh -> None, ContourStyle -> LightRed, MaxRecursion -> 6,
PlotPoints -> 20]
Added alternative:
Another way that happens to remove the branch-cut jump (the use of polar coordinates is similar to Henrik's, but it's the combination with ComplexExpand
that moves the branch cut to the boundary of the plot):
imEVs = FullSimplify[
ComplexExpand[Im@Eigenvalues[H], TargetFunctions -> {Re, Im}],
x > 0 && -1 < y < 1];
ParametricPlot3D[
Evaluate@Thread[{x, y, imEVs}],
{x, 0, 2}, {y, -1, 1}, PlotStyle -> LightRed, Mesh -> None,
Exclusions -> None, BoxRatios -> {1, 1, 1}
]