Efficiently find all values of parameter such that any of the eigenvalues of a matrix is equal to 1
You can use the Arnoldi-Lanczos algorithm to efficiently find the eigenvalue that is closest to a target value (here, target=1
):
closestEVtotarget[x_?NumericQ, target_?NumericQ] :=
First@Eigenvalues[matrix[N[x]], 1,
Method -> {"Arnoldi", "Criteria" -> "Magnitude", "Shift" -> target}]
Then it's a matter of plotting and root-finding:
With[{target = 1},
Plot[closestEVtotarget[x, target], {x, -10, 10}, GridLines -> {None, {target}}]]
With[{target = 1},
FindRoot[closestEVtotarget[x, target] == target, {x, -1}]]
(* {x -> -1.00721} *)
You can start the root-finder either at hand-picked points (glanced from the plot) or at regularly spaced points:
With[{target = 1},
Union[Table[x /. FindRoot[closestEVtotarget[x, target] == target, {x, x0}],
{x0, -2, 9, 1/100}], SameTest -> (Abs[#1 - #2] < 10^-13 &)]]
{-1.00721, -0.395222, 0.169748, 0.713365, 0.82903, 1.07979, 1.54682, 2.14069, 2.79951, 3.25381, 3.53335, 4.12606, 4.57025, 5.25281, 5.45146, 7.72722}
Alternatively we can use the Graphics`Mesh`FindIntersections
function (see 199038, 156975, 10475) to get good starting values geometrically from the plot intersections:
With[{target = 1},
plot = Plot[{target, closestEVtotarget[x, target]}, {x, -10, 10}];
intersections = Graphics`Mesh`FindIntersections[plot]]
{{-1.00725, 1.}, {-0.958231, 1.}, {-0.395304, 1.}, {-0.351347, 1.}, {0.16972, 1.}, {0.292244, 1.}, {0.713331, 1.}, {0.756746, 1.}, {0.828908, 1.}, {0.941439, 1.}, {1.07977, 1.}, {1.10962, 1.}, {1.54678, 1.}, {1.65261, 1.}, {2.14052, 1.}, {2.222, 1.}, {2.79948, 1.}, {2.94262, 1.}, {3.25374, 1.}, {3.28433, 1.}, {3.53329, 1.}, {3.59908, 1.}, {4.12603, 1.}, {4.21907, 1.}, {4.57021, 1.}, {4.64757, 1.}, {5.2528, 1.}, {5.31701, 1.}, {5.4514, 1.}, {5.52141, 1.}, {7.72721, 1.}, {7.85725, 1.}}
Not all of these are useful: some come from branch jumps. Also, they are not very precise. We refine them with FindRoot
:
refined =
Union[x /. FindRoot[closestEVtotarget[x, #[[2]]] == #[[2]], {x, #[[1]]}] & /@
intersections, SameTest -> (Abs[#1 - #2] < 10^-13 &)]
{-1.00721, -0.395222, 0.169748, 0.713365, 0.82903, 1.07979, 1.54682, 2.14069, 2.79951, 3.25381, 3.53335, 4.12606, 4.57025, 5.25281, 5.45146, 7.72722}