Subsections

5. Linear algebra


5.1 Vector spaces

The VectorSpace command creates a vector space class, from which one can create a subspace. Note the basis computed by
SAGE is ``row reduced''.

sage: V = VectorSpace(GF(2),8)
sage: S = V.subspace([V([1,1,0,0,0,0,0,0]),V([1,0,0,0,0,1,1,0])])
sage: S.basis()
      [
      (1, 0, 0, 0, 0, 1, 1, 0),
      (0, 1, 0, 0, 0, 1, 1, 0)
      ]
sage: S.dimension()
      2


5.2 Kernels

The kernel is computed by applying the kernel method to the matrix object. The following examples illustrate the syntax.

sage: M = MatrixSpace(IntegerRing(),4,2)(range(8))
sage: M.kernel()
Free module of degree 4 and rank 2 over Integer Ring
Echelon basis matrix:
[ 1  0 -3  2]
[ 0  1 -2  1]

A kernel of dimension one over $ \mathbb{Q}$ :

sage: A = MatrixSpace(RationalField(),3)(range(9))
sage: A.kernel()
Vector space of degree 3 and dimension 1 over Rational Field
Basis matrix:
[ 1 -2  1]

A trivial kernel:

sage: A = MatrixSpace(RationalField(),2)([1,2,3,4])
sage: A.kernel()
Vector space of degree 2 and dimension 0 over Rational Field
Basis matrix:
[]
sage: M = MatrixSpace(RationalField(),0,2)(0)
sage: M
[]
sage: M.kernel()
Vector space of degree 0 and dimension 0 over Rational Field
Basis matrix:
[]
sage: M = MatrixSpace(RationalField(),2,0)(0)
sage: M.kernel()
Vector space of dimension 2 over Rational Field

Kernel of a zero matrix:

sage: A = MatrixSpace(RationalField(),2)(0)
sage: A.kernel()
Vector space of degree 2 and dimension 2 over Rational Field
Basis matrix:
[1 0]
[0 1]

Kernel of a non-square matrix:

sage: A = MatrixSpace(RationalField(),3,2)(range(6))
sage: A.kernel()
Vector space of degree 3 and dimension 1 over Rational Field
Basis matrix:
[ 1 -2  1]

The 2-dimensional kernel of a matrix over a cyclotomic field:

sage: K = CyclotomicField(12); a = K.gen()
sage: M = MatrixSpace(K,4,2)([1,-1, 0,-2, 0,-a**2-1, 0,a**2-1])
sage: M
[             1             -1]
[             0             -2]
[             0 -zeta12^2 - 1]
[             0  zeta12^2 - 1]
sage: M.kernel()
Vector space of degree 4 and dimension 2 over Cyclotomic Field of order 12 
 and degree 4
Basis matrix:
[               0                1                0     -2*zeta12^2]
[               0                0                1 -2*zeta12^2 + 1]

A nontrivial kernel over a complicated base field.

sage: K = FractionField(MPolynomialRing(RationalField(),2))
sage: M = MatrixSpace(K, 2)([[K.gen(1),K.gen(0)], [K.gen(1), K.gen(0)]])
sage: M
[x1 x0]
[x1 x0]
sage: M.kernel()
Vector space of degree 2 and dimension 1 over Fraction Field of Polynomial Ring in x0, x1 over Rational Field
Basis matrix:
 [ 1 -1]

Other methods for integer matrices are elementary_divisors, smith_form (for the Smith normal form), echelon (a method for integer matrices) for the Hermite normal form, frobenius for the Frobenius normal form (rational canonical form).

There a many methods for matrices over a field such as $ \mathbb{Q}$ or a finite field: row_span, nullity, transpose, swap_rows, matrix_from_columns, matrix_from_rows, among many others.

See the file matrix.py for further details.


5.3 Eigenvectors and eigenvalues

The best approach, for now, is to use the interface with maxima:

sage: A = maxima("A: matrix ([1, -4], [1, -1])")
sage: A
matrix([1, - 4],[1, - 1])
sage: eig = A.eigenvectors()
sage: eig
[[[ - sqrt(3)*%i,sqrt(3)*%i],[1,1]],[1,(sqrt(3)*%i + 1)/4],[1, - (sqrt(3)*%i - 1)/4]]
This tells us that $ \vec{v}_1 = [1,(\sqrt{3}i + 1)/4]$ is an eigenvector of $ \lambda_1 = - \sqrt{3}i$ (which occurs with multiplicity one) and $ \vec{v}_2 = [1,(-\sqrt{3}i + 1)/4]$ is an eigenvector of $ \lambda_2 = \sqrt{3}i$ (which also occurs with multiplicity one).

Here are two more examples:

sage: A = maxima("A: matrix ([11, 0, 0], [1, 11, 0], [1, 3, 2])")
sage: A.eigenvectors()
[[[2,11],[1,2]],[0,0,1],[0,1,1/3]]
sage: A = maxima("A: matrix ([-1, 0, 0], [1, -1, 0], [1, 3, 2])")
sage: A.eigenvectors()
[[[ - 1,2],[2,1]],[0,1, - 1],[0,0,1]]
Warning: Notice how the ordering of the output is reversed, though the matrices are almost the same.


5.4 Row reduction

The row reduced echelon form of a matrix is computed as in the following example.

sage: M = MatrixSpace(RationalField(),2,3)
sage: A = M([1,2,3, 4,5,6])
sage: A
[1 2 3]
[4 5 6]
sage: A.parent()
Full MatrixSpace of 2 by 3 dense matrices over Rational Field
sage: A[0,2] = 389
sage: A
[  1   2 389]
[  4   5   6]
sage: A.echelon_form()
[      1       0 -1933/3]
[      0       1  1550/3]


5.5 Characteristic polynomial

The characteristic polynomial is a SAGE method for square matrices.

First a matrix over $ \mathbb{Z}$ :

sage: A = MatrixSpace(IntegerRing(),2)( [[1,2], [3,4]] )
sage: f = A.charpoly()
sage: f
x^2 - 5*x - 2
sage: f.parent()
Univariate Polynomial Ring in x over Integer Ring

We compute the characteristic polynomial of a matrix over the polynomial ring $ \mathbb{Z}[a]$ :

sage: R = PolynomialRing(IntegerRing(),'a'); a = R.gen()
sage: M = MatrixSpace(R,2)([[a,1], [a,a+1]])
sage: M
[    a     1]
[    a a + 1]
sage: f = M.charpoly()
sage: f
x^2 + (-2*a - 1)*x + a^2
sage: f.parent()
Univariate Polynomial Ring in x over Univariate Polynomial Ring in a over Integer Ring

sage: M.trace()
2*a + 1
sage: M.determinant()
a^2

We compute the characteristic polynomial of a matrix over the multi-variate polynomial ring $ \mathbb{Z}[u,v]$ :

sage: R,(u,v) = Z['u,v'].objgens()
sage: A = MatrixSpace(R,2)([u,v,u**2,v**2])
sage: f = A.charpoly()
sage: f
x^2 + (-1*v^2 - u)*x + u*v^2 - u^2*v

It's a little difficult to distinguish the variables. To fix this, we rename the indeterminate "Z":

sage: f.parent().assign_names("Z")
sage: f
Z^2 + (-1*v^2 - u)*Z + u*v^2 - u^2*v

On a related matter, to compute the eigenvalues and eigenvectors of a matrix, you can use SAGE's GAP interface:

sage: gap.eval("A := [[1,2,3],[4,5,6],[7,8,9]]")
'[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]'
sage: gap.eval("v := Eigenvectors( Rationals,A)")
'[ [ 1, -2, 1 ] ]'
sage: gap.eval("lambda := Eigenvalues( Rationals,A)")
'[ 0 ]'

5.6 Solving systems of linear equations

Using maxima, you can easily solve linear equations:

sage: eqn = maxima(['a+b*c=1', 'b-a*c=0', 'a+b=5'])
sage: s = eqn.solve('[a,b,c]'); s
[[a = (25*sqrt(79)*%i + 25)/(6*sqrt(79)*%i - 34),b = (5*sqrt(79)*%i +
5)/(sqrt(79)*%i + 11),c = (sqrt(79)*%i + 1)/10],[a = (25*sqrt(79)*%i -
25)/(6*sqrt(79)*%i + 34),b = (5*sqrt(79)*%i - 5)/(sqrt(79)*%i - 11),c =  -
(sqrt(79)*%i - 1)/10]]
You can even nicely typeset the solution in latex:

sage: print latex(s)
\left[\left[a = \frac{25\sqrt{79}i + 25}{6\sqrt{79}i - 34},b =
\frac{5\sqrt{79}i + 5}{\sqrt{79}i + 11},c = \frac{\sqrt{79}i +
1}{10}\right],\left[a = \frac{25\sqrt{79}i - 25}{6\sqrt{79}i + 34},b =
\frac{5\sqrt{79}i - 5}{\sqrt{79}i - 11},c =  - \frac{\sqrt{79}i -
1}{10}\right]\right]
To have the above appear onscreen via xdvi, type view(s).

To solve a system numerically, you can use SAGE's octave interface:

sage: M33 = MatrixSpace(QQ,3,3)
sage: A   = M33([1,2,3,4,5,6,7,8,0])
sage: V3  = VectorSpace(QQ,3)
sage: b   = V3([1,2,3])
sage: octave.solve_linear_system(A,b)    # requires optional octave
[-0.33333299999999999, 0.66666700000000001, -3.5236600000000002e-18]

See About this document... for information on suggesting changes.