This is very specific to your polynomial. In general you have to expect that a root of multiplicity m
has a relative floating point error of magnitude mu^(1/m)
where mu=1e-15
is the machine precision. In this case the multiplicity is m=3
, thus the error in the range of 10^(-5)
. Which is exactly the scale of the errors in your results.
That this happens here with clear integer coefficients is a result of the method matlab uses, it computes the eigenvalues of the companion matrix, and the eigenvalue algorithm will transform the integer matrix into a proper floating point matrix with corresponding rounding errors in the first step of the algorithm.
Other algorithms have empirical tests for multiplicities and associated clusters of approximative roots and thus are able to correct this error. In this case you could achieve this by replacing each root by the average of the 3 roots.
Mathematically, you have some polynomial
p(x)=(x-a)^m*q(x)
with a root at x=a
of multiplicity m
. Due to floating point operations, the solver effectively "sees" a polynomial
p(x)+e(x)
where the coefficients of e(x)
have a size that is the magnitude of the coefficients of p
times mu
. Close to the root a
, this perturbed polynomial can be effectively replaced by
(x-a)^m*q(a)+e(a) = 0 <==> (x-a)^m = -e(a)/q(a)
so that the solutions form an m-pointed regular polygon or star centered at a
with radius |e(a)/q(a)|^(1/m)
which should be in the region of |a|*mu^(1/m)
.
isreal(q)
givesfalse
if the arrayq
is complex. But some entries may have zero imaginary part. In fact,isreal(q)
givesfalse
, whereasfor x = q(:).', isreal(x), end
givestrue
,false
,false
. The first entry ofq
is real, the others are not, andq
as a whole is not real – Marquesan