Since Mathematica offers powerful symbolic capabilities I find that more effective solution to the problem uses exact numbers instead of machine precission ones and consequently exploits appropriate symbolic functions.
The given matrix m
:
m = {{0.04 - 0.4 b, 0, 0.04 - 0.4 b},
{0, -0.08 - 1.2 b, -0.06 - 0.9 b},
{1.04 - 0.4 b, 2.08 - 0.8 b, 0}};
we rewrite it to exact (rational) numbers:
matrix = Rationalize @ m
{{ 1/25 - (2 b)/5, 0, 1/25 - (2 b)/5 },
{ 0, -(2/25) - (6 b)/5, -(3/50) - (9 b)/10},
{ 26/25 - (2 b)/5, 52/25 - (4 b)/5, 0} }
Now we can do simply this
sol = Solve[ Thread[ Eigenvalues[ matrix] == 0], b]
{{b -> -(1/15)}, {b -> 1/10}, {b -> 13/5}}
Instead of Thread[ Eigenvalues[matrix] == 0]
one could write Eigenvalues[matrix] == {0, 0, 0}
.
However this solution might be misleading since only one eigenvalue can vanish for every "solution" b
while we explicitely required that all the eigenvalues vanish. Solve
gives generic solutions (see e.g. What is the difference between Reduce and Solve?) thus if we are to find b
when every eigenvalue vanishes then an appropriate approach exploits the MaxExtraConditions
option of Solve
or switches to Reduce
:
Solve[ Thread[ Eigenvalues[matrix] == 0], b, MaxExtraConditions -> All]
{}
Reduce[ Eigenvalues[matrix] == {0, 0, 0}, b]
False
In fact, one can be surprised that simple usage of Solve
seemingly appears to be flawed, nevertheless the Root
objects are responsible for this issue and basically it is an instance of inevitable operational incompatibility of different symbolic functions.
Now let's look at the output we can get with Solve
:
matrixS = matrix /. sol;
MatrixForm /@ matrixS
and these are eigenvalues
Eigenvalues /@ matrixS
{{ 1/30 (1 + Sqrt[65]), 1/30 (1 - Sqrt[65]), 0},
{ 1/10 (-1 + I Sqrt[29]), 1/10 (-1 - I Sqrt[29]), 0},
{ -(16/5), -1, 0} }
Edit
To underline that curious behaviour mentioned above let's consider eigenvalues in terms of Root[ poly[b], k]
objects involving a parameter b
with different numbers k
. A critical issue is to realize that enumeration of roots depends on their values and may change when b
changes. This plot clarifies the problem, here we use:
rt[k_] := Root[-26 - 120 b + 3950 b^2 - 1500 b^3 + (250 + 7000 b - 1250 b^2) #1
+ (125 + 5000 b) #1^2 + 3125 #1^3 &, k] /. b -> x + I y /. x -> 1/10
Plot[ Re[ rt[#]& /@ {1, 2, 3}], {y, -1, 1}, Evaluated -> True,
PlotStyle -> Thickness[0.006], ImageSize -> 560,
PlotLegends -> Placed[Automatic, Below]]
The above problems may be prevented with ToRadicals
, compare e.g.
Solve[ Root[-26 - 120 b + 3950 b^2 - 1500 b^3 + (250 + 7000 b - 1250 b^2) #1
+ (125 + 5000 b) #1^2 + 3125 #1^3 &, 2] == 0, b]
{{b -> -(1/15)}, {b -> 1/10}, {b -> 13/5}}
Solve[ ToRadicals[
Root[-26 - 120 b + 3950 b^2 - 1500 b^3 + (250 + 7000 b - 1250 b^2) #1
+ (125 + 5000 b) #1^2 + 3125 #1^3 &, 2]] == 0, b]
{}