# Symbolic matrices¶

Symbolic matrices

Matrices with symbolic entries. The underlying representation is a pointer to a Maxima object.

EXAMPLES:

```sage: matrix(SR, 2, 2, range(4))
[0 1]
[2 3]
sage: matrix(SR, 2, 2, var('t'))
[t 0]
[0 t]
```

Arithmetic:

```sage: -matrix(SR, 2, range(4))
[ 0 -1]
[-2 -3]
sage: m = matrix(SR, 2, [1..4]); sqrt(2)*m
[  sqrt(2) 2*sqrt(2)]
[3*sqrt(2) 4*sqrt(2)]    
sage: m = matrix(SR, 4, [1..4^2])
sage: m * m
[ 90 100 110 120]
[202 228 254 280]
[314 356 398 440]
[426 484 542 600]

sage: m = matrix(SR, 3, [1, 2, 3]); m
[1]
[2]
[3]
sage: m.transpose() * m
[14]
```

Computing inverses:

```sage: M = matrix(SR, 2, var('a,b,c,d'))
sage: ~M
[-b*c/((b*c/a - d)*a^2) + 1/a            b/((b*c/a - d)*a)]
[           c/((b*c/a - d)*a)               -1/(b*c/a - d)]
sage: (~M*M).simplify_rational()
[1 0]
[0 1]
sage: M = matrix(SR, 3, 3, range(9)) - var('t')
sage: (~M * M).simplify_rational()
[1 0 0]
[0 1 0]
[0 0 1]

sage: matrix(SR, 1, 1, 1).inverse()
[1]        
sage: matrix(SR, 0, 0).inverse()
[]
sage: matrix(SR, 3, 0).inverse()
Traceback (most recent call last):
...
ArithmeticError: self must be a square matrix
```

Transposition:

```sage: m = matrix(SR, 2, [sqrt(2), -1, pi, e^2])
sage: m.transpose()
[sqrt(2)      pi]
[     -1     e^2]
```

.T is a convenient shortcut for the transpose:

```sage: m.T
[sqrt(2)      pi]
[     -1     e^2]
```

Test pickling:

```sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e]); m
[sqrt(2)       3]
[     pi       e]
sage: TestSuite(m).run()
```

Comparison:

```sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e])
sage: cmp(m,m)
0
sage: cmp(m,3) != 0
True
sage: m = matrix(SR,2,[1..4]); n = m^2
sage: (exp(m+n) - exp(m)*exp(n)).simplify_rational() == 0       # indirect test
True
```

Determinant:

```sage: M = matrix(SR, 2, 2, [x,2,3,4])
sage: M.determinant()
4*x - 6
sage: M = matrix(SR, 3,3,range(9))
sage: M.det()
0
sage: t = var('t')
sage: M = matrix(SR, 2, 2, [cos(t), sin(t), -sin(t), cos(t)])
sage: M.det()
sin(t)^2 + cos(t)^2
```

Permanents:

```sage: M = matrix(SR, 2, 2, [x,2,3,4])
sage: M.permanent()
4*x + 6            
```

Rank:

```sage: M = matrix(SR, 5, 5, range(25))
sage: M.rank()
2
sage: M = matrix(SR, 5, 5, range(25)) - var('t')
sage: M.rank()
5

.. warning::

    :meth:`rank` may return the wrong answer if it cannot determine that a
    matrix element that is equivalent to zero is indeed so.
```

Copying symbolic matrices:

```sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e])
sage: n = copy(m)
sage: n[0,0] = sin(1)
sage: m
[sqrt(2)       3]
[     pi       e]
sage: n
[sin(1)      3]
[    pi      e]
```

Conversion to Maxima:

```sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e])
sage: m._maxima_()
matrix([sqrt(2),3],[%pi,%e])
```
class sage.matrix.matrix_symbolic_dense.Matrix_symbolic_dense¶

Bases: sage.matrix.matrix_generic_dense.Matrix_generic_dense

See Matrix_generic_dense for documentation.

TESTS:

We check that the problem related to Trac #9049 is not an issue any more:

```sage: S.<t>=PolynomialRing(QQ)
sage: F.<q>=QQ.extension(t^4+1)
sage: R.<x,y>=PolynomialRing(F)
sage: M = MatrixSpace(R, 1, 2)
sage: from sage.matrix.matrix_generic_dense import Matrix_generic_dense
sage: Matrix_generic_dense(M, (x, y), True, True)
[x y]
```
arguments()¶

Returns a tuple of the arguments that self can take.

EXAMPLES:

```sage: var('x,y,z')
(x, y, z)
sage: M = MatrixSpace(SR,2,2)
sage: M(x).arguments()
(x,)
sage: M(x+sin(x)).arguments()
(x,)
```
charpoly(var='x', algorithm=None)¶

Compute the characteristic polynomial of self, using maxima.

EXAMPLES:

```sage: M = matrix(SR, 2, 2, var('a,b,c,d'))
sage: M.charpoly('t')
t^2 + (-a - d)*t + a*d - b*c
sage: matrix(SR, 5, [1..5^2]).charpoly()
x^5 - 65*x^4 - 250*x^3
```

TESTS:

The cached polynomial should be independent of the var argument (trac ticket #12292). We check (indirectly) that the second call uses the cached value by noting that its result is not cached:

```sage: M = MatrixSpace(SR, 2)
sage: A = M(range(0, 2^2))
sage: type(A)
<type 'sage.matrix.matrix_symbolic_dense.Matrix_symbolic_dense'>
sage: A.charpoly('x')
x^2 - 3*x - 2
sage: A.charpoly('y')
y^2 - 3*y - 2
sage: A._cache['charpoly']
x^2 - 3*x - 2
```
eigenvalues(solution_set=False)¶

Compute the eigenvalues by solving the characteristic polynomial in maxima

EXAMPLES:

```sage: a=matrix(SR,[[1,2],[3,4]])
sage: a.eigenvalues()
[-1/2*sqrt(33) + 5/2, 1/2*sqrt(33) + 5/2]
```
eigenvectors_left()¶

Compute the left eigenvectors of a matrix.

For each distinct eigenvalue, returns a list of the form (e,V,n) where e is the eigenvalue, V is a list of eigenvectors forming a basis for the corresponding left eigenspace, and n is the algebraic multiplicity of the eigenvalue.

EXAMPLES:

```sage: A = matrix(SR,3,3,range(9)); A
[0 1 2]
[3 4 5]
[6 7 8]
sage: es = A.eigenvectors_left(); es
[(-3*sqrt(6) + 6, [(1, -1/5*sqrt(6) + 4/5, -2/5*sqrt(2)*sqrt(3) + 3/5)], 1), (3*sqrt(6) + 6, [(1, 1/5*sqrt(6) + 4/5, 2/5*sqrt(2)*sqrt(3) + 3/5)], 1), (0, [(1, -2, 1)], 1)]
sage: eval, [evec], mult = es[0]
sage: delta = eval*evec - evec*A
sage: abs(abs(delta)) < 1e-10
abs(sqrt(144/25*(sqrt(2)*sqrt(3) - sqrt(6))^2 + 1/25*(3*(sqrt(6) - 2)*(2*sqrt(2)*sqrt(3) - 3) + 16*sqrt(2)*sqrt(3) + 5*sqrt(6) - 54)^2 + 1/25*(3*(sqrt(6) - 4)*(sqrt(6) - 2) + 14*sqrt(2)*sqrt(3) + 4*sqrt(6) - 42)^2)) < (1.00000000000000e-10)
sage: abs(abs(delta)).n() < 1e-10
True
```
```sage: A = matrix(SR, 2, 2, var('a,b,c,d'))
sage: A.eigenvectors_left()
[(1/2*a + 1/2*d - 1/2*sqrt(a^2 - 2*a*d + 4*b*c + d^2), [(1, -1/2*(a - d + sqrt(a^2 - 2*a*d + 4*b*c + d^2))/c)], 1), (1/2*a + 1/2*d + 1/2*sqrt(a^2 - 2*a*d + 4*b*c + d^2), [(1, -1/2*(a - d - sqrt(a^2 - 2*a*d + 4*b*c + d^2))/c)], 1)]
sage: es = A.eigenvectors_left(); es
[(1/2*a + 1/2*d - 1/2*sqrt(a^2 - 2*a*d + 4*b*c + d^2), [(1, -1/2*(a - d + sqrt(a^2 - 2*a*d + 4*b*c + d^2))/c)], 1), (1/2*a + 1/2*d + 1/2*sqrt(a^2 - 2*a*d + 4*b*c + d^2), [(1, -1/2*(a - d - sqrt(a^2 - 2*a*d + 4*b*c + d^2))/c)], 1)]
sage: eval, [evec], mult = es[0]
sage: delta = eval*evec - evec*A
sage: delta.apply_map(lambda x: x.full_simplify())
(0, 0)
```

This routine calls Maxima and can struggle with even small matrices with a few variables, such as a $$3\times 3$$ matrix with three variables. However, if the entries are integers or rationals it can produce exact values in a reasonable time. These examples create 0-1 matrices from the adjacency matrices of graphs and illustrate how the format and type of the results differ when the base ring changes. First for matrices over the rational numbers, then the same matrix but viewed as a symbolic matrix.

```sage: G=graphs.CycleGraph(5)
sage: am = G.adjacency_matrix()
sage: spectrum = am.eigenvectors_left()
sage: qqbar_evalue = spectrum[2][0]
sage: type(qqbar_evalue)
<class 'sage.rings.qqbar.AlgebraicNumber'>
sage: qqbar_evalue
0.618033988749895?

sage: am = G.adjacency_matrix().change_ring(SR)
sage: spectrum = am.eigenvectors_left()
sage: symbolic_evalue = spectrum[2][0]
sage: type(symbolic_evalue)
<type 'sage.symbolic.expression.Expression'>
sage: symbolic_evalue
1/2*sqrt(5) - 1/2

sage: qqbar_evalue == symbolic_evalue
True
```

A slightly larger matrix with a “nice” spectrum.

```sage: G=graphs.CycleGraph(6)
sage: am = G.adjacency_matrix().change_ring(SR)
sage: am.eigenvectors_left()
[(-1, [(1, 0, -1, 1, 0, -1), (0, 1, -1, 0, 1, -1)], 2), (1, [(1, 0, -1, -1, 0, 1), (0, 1, 1, 0, -1, -1)], 2), (-2, [(1, -1, 1, -1, 1, -1)], 1), (2, [(1, 1, 1, 1, 1, 1)], 1)]
```
eigenvectors_right()¶

Compute the right eigenvectors of a matrix.

For each distinct eigenvalue, returns a list of the form (e,V,n) where e is the eigenvalue, V is a list of eigenvectors forming a basis for the corresponding right eigenspace, and n is the algebraic multiplicity of the eigenvalue.

EXAMPLES:

```sage: A = matrix(SR,2,2,range(4)); A
[0 1]
[2 3]
sage: right = A.eigenvectors_right(); right
[(-1/2*sqrt(17) + 3/2, [(1, -1/2*sqrt(17) + 3/2)], 1), (1/2*sqrt(17) + 3/2, [(1, 1/2*sqrt(17) + 3/2)], 1)]
```

The right eigenvectors are nothing but the left eigenvectors of the transpose matrix:

```sage: left  = A.transpose().eigenvectors_left(); left
[(-1/2*sqrt(17) + 3/2, [(1, -1/2*sqrt(17) + 3/2)], 1), (1/2*sqrt(17) + 3/2, [(1, 1/2*sqrt(17) + 3/2)], 1)]
sage: right[0][1] == left[0][1]
True
```
exp()¶

Return the matrix exponential of this matrix $$X$$, which is the matrix

$e^X = \sum_{k=0}^{\infty} \frac{X^k}{k!}.$

This function depends on maxima’s matrix exponentiation function, which does not deal well with floating point numbers. If the matrix has floating point numbers, they will be rounded automatically to rational numbers during the computation.

EXAMPLES:

```sage: m = matrix(SR,2, [0,x,x,0]); m
[0 x]
[x 0]
sage: m.exp()
[1/2*(e^(2*x) + 1)*e^(-x) 1/2*(e^(2*x) - 1)*e^(-x)]
[1/2*(e^(2*x) - 1)*e^(-x) 1/2*(e^(2*x) + 1)*e^(-x)]
sage: exp(m)
[1/2*(e^(2*x) + 1)*e^(-x) 1/2*(e^(2*x) - 1)*e^(-x)]
[1/2*(e^(2*x) - 1)*e^(-x) 1/2*(e^(2*x) + 1)*e^(-x)]
```

Exp works on 0x0 and 1x1 matrices:

```sage: m = matrix(SR,0,[]); m
[]
sage: m.exp()
[]
sage: m = matrix(SR,1,[2]); m
[2]
sage: m.exp()
[e^2]
```

Commuting matrices $$m, n$$ have the property that $$e^{m+n} = e^m e^n$$ (but non-commuting matrices need not):

```sage: m = matrix(SR,2,[1..4]); n = m^2
sage: m*n
[ 37  54]
[ 81 118]
sage: n*m
[ 37  54]
[ 81 118]

sage: a = exp(m+n) - exp(m)*exp(n)
sage: a.simplify_rational() == 0
True
```

The input matrix must be square:

```sage: m = matrix(SR,2,3,[1..6]); exp(m)
Traceback (most recent call last):
...
ValueError: exp only defined on square matrices
```

In this example we take the symbolic answer and make it numerical at the end:

```sage: exp(matrix(SR, [[1.2, 5.6], [3,4]])).change_ring(RDF)
[346.557487298 661.734590934]
[354.500673715 677.424782765]
```

Another example involving the reversed identity matrix, which we clumsily create:

```sage: m = identity_matrix(SR,4); m = matrix(list(reversed(m.rows()))) * x
sage: exp(m)
[1/2*(e^(2*x) + 1)*e^(-x)                        0                        0 1/2*(e^(2*x) - 1)*e^(-x)]
[                       0 1/2*(e^(2*x) + 1)*e^(-x) 1/2*(e^(2*x) - 1)*e^(-x)                        0]
[                       0 1/2*(e^(2*x) - 1)*e^(-x) 1/2*(e^(2*x) + 1)*e^(-x)                        0]
[1/2*(e^(2*x) - 1)*e^(-x)                        0                        0 1/2*(e^(2*x) + 1)*e^(-x)]
```
expand()¶

Operates point-wise on each element.

EXAMPLES:

```sage: M = matrix(2, 2, range(4)) - var('x')
sage: M*M
[      x^2 + 2      -2*x + 3]
[     -4*x + 6 (x - 3)^2 + 2]
sage: (M*M).expand()
[       x^2 + 2       -2*x + 3]
[      -4*x + 6 x^2 - 6*x + 11]
```
factor()¶

Operates point-wise on each element.

EXAMPLES:

```sage: M = matrix(SR, 2, 2, x^2 - 2*x + 1); M
[x^2 - 2*x + 1             0]
[            0 x^2 - 2*x + 1]
sage: M.factor()
[(x - 1)^2         0]
[        0 (x - 1)^2]
```
fcp(var='x')¶

Return the factorization of the characteristic polynomial of self.

INPUT:

• var - (default: ‘x’) name of variable of charpoly

EXAMPLES:

```sage: a = matrix(SR,[[1,2],[3,4]])
sage: a.fcp()
x^2 - 5*x - 2
sage: [i for i in a.fcp()]
[(x^2 - 5*x - 2, 1)]
sage: a = matrix(SR,[[1,0],[0,2]])
sage: a.fcp()
(x - 2) * (x - 1)
sage: [i for i in a.fcp()]
[(x - 2, 1), (x - 1, 1)]
sage: a = matrix(SR, 5, [1..5^2]) 
sage: a.fcp()
(x^2 - 65*x - 250) * x^3
sage: list(a.fcp())
[(x^2 - 65*x - 250, 1), (x, 3)]
```
is_simplified()¶

Return True if self is the result of running simplify() on a symbolic matrix. This has the semantics of ‘has_been_simplified’.

EXAMPLES:

```sage: var('x,y,z')
(x, y, z)
sage: m = matrix([[z, (x+y)/(x+y)], [x^2, y^2+2]]); m
[      z       1]
[    x^2 y^2 + 2]
sage: m.is_simplified()
doctest:...: DeprecationWarning: is_simplified is deprecated
See http://trac.sagemath.org/6115 for details.
False
sage: ms = m.simplify(); ms
[      z       1]
[    x^2 y^2 + 2]

sage: m.is_simplified()
False
sage: ms.is_simplified()
False
```
number_of_arguments()¶

Returns the number of arguments that self can take.

EXAMPLES:

```sage: var('a,b,c,x,y')
(a, b, c, x, y)
sage: m = matrix([[a, (x+y)/(x+y)], [x^2, y^2+2]]); m
[      a       1]
[    x^2 y^2 + 2]
sage: m.number_of_arguments()
3
```
simplify()¶

Simplifies self.

EXAMPLES:

```sage: var('x,y,z')
(x, y, z)
sage: m = matrix([[z, (x+y)/(x+y)], [x^2, y^2+2]]); m
[      z       1]
[    x^2 y^2 + 2]
sage: m.simplify()
[      z       1]
[    x^2 y^2 + 2]            
```
simplify_rational()¶

EXAMPLES:

```sage: M = matrix(SR, 3, 3, range(9)) - var('t')
sage: (~M*M)[0,0]
-(3*((6/t + 7)/((t - 3/t - 4)*t) + 2/t)*((6/t + 5)/((t - 3/t - 4)*t) + 2/t)/((6/t + 5)*(6/t + 7)/(t - 3/t - 4) - t + 12/t + 8) - 1/t - 3/((t - 3/t - 4)*t^2))*t + 3*(6/t + 7)*((6/t + 5)/((t - 3/t - 4)*t) + 2/t)/((t - 3/t - 4)*((6/t + 5)*(6/t + 7)/(t - 3/t - 4) - t + 12/t + 8)) + 6*((6/t + 5)/((t - 3/t - 4)*t) + 2/t)/((6/t + 5)*(6/t + 7)/(t - 3/t - 4) - t + 12/t + 8) - 3/((t - 3/t - 4)*t)
sage: expand((~M*M)[0,0])
1
sage: (~M * M).simplify_rational()
[1 0 0]
[0 1 0]
[0 0 1]
```
simplify_trig()¶

EXAMPLES:

```sage: theta = var('theta')
sage: M = matrix(SR, 2, 2, [cos(theta), sin(theta), -sin(theta), cos(theta)])
sage: ~M
[-sin(theta)^2/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta)^2) + 1/cos(theta)                    -sin(theta)/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta))]
[                    sin(theta)/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta))                                           1/(sin(theta)^2/cos(theta) + cos(theta))]
sage: (~M).simplify_trig()
[ cos(theta) -sin(theta)]
[ sin(theta)  cos(theta)]
```
variables()¶

Returns the variables of self.

EXAMPLES:

```sage: var('a,b,c,x,y')
(a, b, c, x, y)
sage: m = matrix([[x, x+2], [x^2, x^2+2]]); m
[      x   x + 2]
[    x^2 x^2 + 2]
sage: m.variables()
(x,)
sage: m = matrix([[a, b+c], [x^2, y^2+2]]); m
[      a   b + c]
[    x^2 y^2 + 2]
sage: m.variables()
(a, b, c, x, y)
```

#### Previous topic

Sparse matrices over $$\ZZ/n\ZZ$$ for $$n$$ small

#### Next topic

Dense matrices over the integer ring

### Quick search

Enter search terms or a module, class or function name.
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 1, "mathjax_display_tex": 6, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 20, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "github"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "english_confidence": 0.7191084027290344, "perplexity_flag": "middle"}