Matrices
Symbolica documentation for getting started, symbolic expressions, numerical evaluation, pattern matching, and APIs in Python and Rust.
The Matrix data structure allows users to do linear algebra operations in Symbolica.
Construction
Matrices can be created through one of the following constructors:
from symbolica import *
i = Matrix.identity(2)
e = Matrix.eye([1, 2, 3])
l = Matrix.from_linear(3, 2, [1, 2, 3, 4, 5, 6])
n = Matrix.from_nested([[1, 2, 3], [4, 5, 6]])use symbolica::prelude::*;
fn main() {
let i = Matrix::identity(2, IntegerRing::new());
let e = Matrix::identity(&[1.into(), 2.into(), 3.into()], IntegerRing::new());
let l = Matrix::from_linear(
vec![
1u64.into(),
2u64.into(),
3u64.into(),
4u64.into(),
5u64.into(),
6u64.into(),
],
3,
2,
IntegerRing::new(),
)
.unwrap();
let n = Matrix::from_nested(
vec![
vec![1.into(), 2.into(), 3.into()],
vec![4.into(), 5.into(), 6.into()],
],
IntegerRing::new(),
)
.unwrap();
}Output
i = {{1,0},{0,1}}
e = {{1,0,0},{0,2,0},{0,0,3}}
l = {{1,2},{3,4},{5,6}}
n = {{1,2,3},{4,5,6}}
Arithmetic
Matrices can be multiplied, added and subtracted using overloaded operators.
l = Matrix.from_linear(3, 2, [1, 2, 3, 4, 5, 6])
n = Matrix.from_nested([[1, 2, 3], [4, 5, 6]])
l * n + Matrix.identity(3)use symbolica::prelude::*;
let c = &l * &n + &Matrix::identity(3, IntegerRing::new());Output
{{10,12,15},{19,27,33},{29,40,52}}
In Rust, the type of argument of the matrix can be selected, e.g. Matrix<Rational>. In Python, the default is a matrix over rational polynomials, i.e. Matrix<RationalPolynomial<Integer, u16>> in Rust.
Common operations
For matrices over fields, determinants and inverses can be computed.
t = Expression.symbol('t')
a = Matrix.from_nested([[t, 2], [3, 4]])
print('a =', a)
print('a^-1 =', a.inv())
print('det(a) =', a.det())use symbolica::prelude::*;
println!("a = {}", a);
println!("a^-1 = {}", a.inv().unwrap());
println!("det(a) = {}", a.det().unwrap());Output
a = {{t,2},{3,4}}
a^-1 = {{2/(-3+2*t),-3/(-6+4*t)},{-3/(-6+4*t),t/(-6+4*t)}}
det(a) = -6+4*t
The matrix equation \[\mathbf{A} \cdot \vec{x} = \vec{b}\] can be solved as well:
from symbolica import *
t = Expression.symbol('t')
a = Matrix.from_nested([[t, 2], [3, 4]])
a.solve(Matrix.vec([4, 3]))use symbolica::prelude::*;
let r = a.solve(&b).unwrap();
println!("{} . x = {} => x = {}", a, b, r);Output
{{5/(-3+2*t)},{(-12+3*t)/(-6+4*t)}}
Matrices can also be indexed using a (row, column) tuple, which yields the entry.