Matrices

Symbolica documentation for getting started, symbolic expressions, numerical evaluation, pattern matching, and APIs in Python and Rust.

Run Symbolica in your browser

Python examples with a Run button can be edited and run here. The first run loads Python, Symbolica, hover documentation, and code completion.

Use display(expr) to pretty-print an intermediate result. The last expression is displayed automatically.

The Matrix data structure allows users to do linear algebra operations in Symbolica.

Construction

Constructors validate matrix shapes: nested rows must have equal lengths, and linear data must have exactly rows * columns entries. 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]])

display("i =", i)
display("e =", e)
display("l =", l)
n
use symbolica::prelude::*;

fn main() {
    let i = Matrix::identity(2, IntegerRing::new());
    let e = Matrix::eye(&[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![
            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.

from symbolica import *

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::*;

fn main() {
    let l = Matrix::from_linear(vec![1.into(), 2.into(), 3.into(), 4.into(), 5.into(), 6.into()], 3, 2, Z).unwrap();
    let n = Matrix::from_nested_vec(vec![vec![1.into(), 2.into(), 3.into()], vec![4.into(), 5.into(), 6.into()]], Z).unwrap();
    let c = &(&l * &n) + &Matrix::identity(3, Z);
    println!("{c}");
}

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<Q>. 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. Inverting a singular matrix raises an error in Python and returns an error in Rust.

from symbolica import *

t = Expression.symbol('t')

a = Matrix.from_nested([[t, 2], [3, 4]])
display('a       =', a)
display('a^-1    =', a.inv())
display('det(a)  =', a.det())

Here we specialize t = 1 and use rational coefficients.

use symbolica::prelude::*;

fn main() {
    let a: Matrix<Q> = Matrix::from_nested_vec(
        vec![vec![1.into(), 2.into()], vec![3.into(), 4.into()]], Q,
    ).unwrap();
    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),-1/(-3+2*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]))

Here we specialize t = 1 and use rational coefficients.

use symbolica::prelude::*;

fn main() {
    let a: Matrix<Q> = Matrix::from_nested_vec(
        vec![vec![1.into(), 2.into()], vec![3.into(), 4.into()]], Q,
    ).unwrap();
    let b = Matrix::from_nested_vec(vec![vec![4.into()], vec![3.into()]], Q).unwrap();
    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.