Skip to content

Commit f69efec

Browse files
committed
define minpoly_lin for matrices over any field
1 parent 7ef5433 commit f69efec

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

src/sage/matrix/matrix2.pyx

+55
Original file line numberDiff line numberDiff line change
@@ -3035,6 +3035,61 @@ cdef class Matrix(Matrix1):
30353035
self.cache('minpoly', mp)
30363036
return mp
30373037

3038+
def minpoly_lin(self, var='x', **kwds):
3039+
r"""
3040+
Return the minimal polynomial of ``self``.
3041+
3042+
This uses a purely linear-algebraic algorithm (essentially
3043+
Gaussian elimination, applied to the powers of ``self``).
3044+
It is slow but it requires no factorization of polynomials.
3045+
3046+
EXAMPLES::
3047+
3048+
sage: # needs sage.rings.finite_rings
3049+
sage: A = matrix(GF(9, 'c'), 4, [1,1,0,0, 0,1,0,0, 0,0,5,0, 0,0,0,5])
3050+
sage: A.minpoly_lin()
3051+
x^3 + 2*x^2 + 2*x + 1
3052+
sage: A.minpoly_lin()(A) == 0
3053+
True
3054+
sage: CF = CyclotomicField()
3055+
sage: i = CF.gen(4)
3056+
sage: A = matrix(CF, 4, [1,1,0,0, 0,1,0,0, 0,0,1+i,0, 0,0,0,-i])
3057+
sage: A.minpoly_lin()
3058+
x^4 - 3*x^3 + (4 - E(4))*x^2 + (-3 + 2*E(4))*x + 1 - E(4)
3059+
3060+
The default variable name is `x`, but you can specify
3061+
another name::
3062+
3063+
sage: # needs sage.rings.finite_rings
3064+
sage: A.minpoly_lin('y')
3065+
y^4 - 3*y^3 + (4 - E(4))*y^2 + (-3 + 2*E(4))*y + 1 - E(4)
3066+
"""
3067+
f = self.fetch('minpoly')
3068+
if f is not None:
3069+
return f.change_variable_name(var)
3070+
3071+
n = self.nrows()
3072+
F = self.base_ring()
3073+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
3074+
P = PolynomialRing(F, "x")
3075+
x = P.gen()
3076+
from sage.modules.free_module_element import vector
3077+
from sage.matrix.constructor import matrix
3078+
3079+
pow = self**0
3080+
pows = []
3081+
for k in range(n+1):
3082+
pows.append(vector(pow.list()))
3083+
pow *= self
3084+
Mpows = matrix(pows)
3085+
try:
3086+
cs = Mpows.solve_left(vector(pow.list()))
3087+
except ValueError:
3088+
continue
3089+
mp = x**(k+1) - P.sum(cs[i] * x**i for i in range(k+1))
3090+
self.cache('minpoly', mp)
3091+
return mp
3092+
30383093
def _test_minpoly(self, **options):
30393094
"""
30403095
Check that :meth:`minpoly` works.

0 commit comments

Comments
 (0)