# Linear Algebra¶

Linear algebra module for internal usage: `ezdxf.math.linalg`

## Functions¶

ezdxf.math.linalg.tridiagonal_vector_solver(A: List[List[float]], B: Iterable[float]) list[float]

Solves the linear equation system given by a tri-diagonal nxn Matrix A . x = B, right-hand side quantities as vector B. Matrix A is diagonal matrix defined by 3 diagonals [-1 (a), 0 (b), +1 (c)].

Note: a0 is not used but has to be present, cn-1 is also not used and must not be present.

If an `ZeroDivisionError` exception occurs, the equation system can possibly be solved by `BandedMatrixLU(A, 1, 1).solve_vector(B)`

Parameters:
• A

diagonal matrix [[a0..an-1], [b0..bn-1], [c0..cn-1]]

```[[b0, c0, 0, 0, ...],
[a1, b1, c1, 0, ...],
[0, a2, b2, c2, ...],
... ]
```

• B – iterable of floats [[b1, b1, …, bn]

Returns:

list of floats

Raises:

ZeroDivisionError – singular matrix

ezdxf.math.linalg.tridiagonal_matrix_solver(A: List[List[float]] | ndarray[Any, dtype[float64]], B: List[List[float]] | ndarray[Any, dtype[float64]])

Solves the linear equation system given by a tri-diagonal nxn Matrix A . x = B, right-hand side quantities as nxm Matrix B. Matrix A is diagonal matrix defined by 3 diagonals [-1 (a), 0 (b), +1 (c)].

Note: a0 is not used but has to be present, cn-1 is also not used and must not be present.

If an `ZeroDivisionError` exception occurs, the equation system can possibly be solved by `BandedMatrixLU(A, 1, 1).solve_vector(B)`

Parameters:
• A

diagonal matrix [[a0..an-1], [b0..bn-1], [c0..cn-1]]

```[[b0, c0, 0, 0, ...],
[a1, b1, c1, 0, ...],
[0, a2, b2, c2, ...],
... ]
```

• B – matrix [[b11, b12, …, b1m], [b21, b22, …, b2m], … [bn1, bn2, …, bnm]]

Returns:

matrix as `Matrix` object

Raises:

ZeroDivisionError – singular matrix

ezdxf.math.linalg.banded_matrix(A: Matrix, check_all=True) tuple[Matrix, int, int]

Transform matrix A into a compact banded matrix representation. Returns compact representation as `Matrix` object and lower- and upper band count m1 and m2.

Parameters:
• A – input `Matrix`

• check_all – check all diagonals if `True` or abort testing after first all zero diagonal if `False`.

ezdxf.math.linalg.detect_banded_matrix(A: Matrix, check_all=True) tuple[int, int]

Returns lower- and upper band count m1 and m2.

Parameters:
• A – input `Matrix`

• check_all – check all diagonals if `True` or abort testing after first all zero diagonal if `False`.

ezdxf.math.linalg.compact_banded_matrix(A: Matrix, m1: int, m2: int)

Returns compact banded matrix representation as `Matrix` object.

Parameters:
• A – matrix to transform

• m1 – lower band count, excluding main matrix diagonal

• m2 – upper band count, excluding main matrix diagonal

## Matrix Class¶

class ezdxf.math.linalg.Matrix(items: Any = None, shape: Tuple[int, int] | None = None, matrix: List[List[float]] | ndarray[Any, dtype[float64]] | None = None)

Basic matrix implementation based `numpy.ndarray`. Matrix data is stored in row major order, this means in a list of rows, where each row is a list of floats.

Initialization:

• Matrix(shape=(rows, cols)) … new matrix filled with zeros

• Matrix(matrix[, shape=(rows, cols)]) … from copy of matrix and optional reshape

• Matrix([[row_0], [row_1], …, [row_n]]) … from Iterable[Iterable[float]]

• Matrix([a1, a2, …, an], shape=(rows, cols)) … from Iterable[float] and shape

Changed in version 1.2: Implementation based on `numpy.ndarray`.

matrix

matrix data as `numpy.ndarray`

nrows

Count of matrix rows.

ncols

Count of matrix columns.

shape

Shape of matrix as (n, m) tuple for n rows and m columns.

append_col(items: Sequence[float]) None

Append a column to the matrix.

append_row(items: Sequence[float]) None

Append a row to the matrix.

col(index: int) list[float]

Return column index as list of floats.

cols() list[list[float]]

Return a list of all columns.

determinant() float

Returns determinant of matrix, raises `ZeroDivisionError` if matrix is singular.

diag(index: int) list[float]

Returns diagonal index as list of floats.

An index of 0 specifies the main diagonal, negative values specifies diagonals below the main diagonal and positive values specifies diagonals above the main diagonal.

e.g. given a 4x4 matrix:

• index 0 is [00, 11, 22, 33],

• index -1 is [10, 21, 32] and

• index +1 is [01, 12, 23]

freeze()

Returns a frozen matrix, all data is stored in immutable tuples.

classmethod identity(shape: Tuple[int, int])

Returns the identity matrix for configuration shape.

inverse()

Returns inverse of matrix as new object.

isclose(other: object) bool

Returns `True` if matrices are close to equal, tolerance value for comparison is adjustable by the attribute `Matrix.abs_tol`.

static reshape(items: Iterable[float], shape: Tuple[int, int])

Returns a new matrix for iterable items in the configuration of shape.

row(index: int) list[float]

Returns row index as list of floats.

rows() list[list[float]]

Return a list of all rows.

set_col(index: int, items: float | Iterable[float] = 1.0) None

Set column values to a fixed value or from an iterable of floats.

set_diag(index: int = 0, items: float | Iterable[float] = 1.0) None

Set diagonal values to a fixed value or from an iterable of floats.

An index of `0` specifies the main diagonal, negative values specifies diagonals below the main diagonal and positive values specifies diagonals above the main diagonal.

e.g. given a 4x4 matrix: index `0` is [00, 11, 22, 33], index `-1` is [10, 21, 32] and index `+1` is [01, 12, 23]

set_row(index: int, items: float | Iterable[float] = 1.0) None

Set row values to a fixed value or from an iterable of floats.

transpose()

Returns a new transposed matrix.

__getitem__(item: tuple[int, int]) float

Get value by (row, col) index tuple, fancy slicing as known from numpy is not supported.

__setitem__(item: tuple[int, int], value: float)

Set value by (row, col) index tuple, fancy slicing as known from numpy is not supported.

__eq__(other: object) bool

Returns `True` if matrices are equal.

__add__(other: Matrix | float)

Matrix addition by another matrix or a float, returns a new matrix.

__sub__(other: Matrix | float)

Matrix subtraction by another matrix or a float, returns a new matrix.

__mul__(other: Matrix | float)

Matrix multiplication by another matrix or a float, returns a new matrix.

## NumpySolver¶

class ezdxf.math.linalg.NumpySolver(A: List[List[float]] | ndarray[Any, dtype[float64]])

Replaces in v1.2 the `LUDecomposition` solver.

solve_vector(B: Iterable[float]) list[float]

Solves the linear equation system given by the nxn Matrix A . x = B, right-hand side quantities as vector B with n elements.

Parameters:

B – vector [b1, b2, …, bn]

Raises:

numpy.linalg.LinAlgError – singular matrix

solve_matrix(B: List[List[float]] | ndarray[Any, dtype[float64]])

Solves the linear equation system given by the nxn Matrix A . x = B, right-hand side quantities as nxm Matrix B.

Parameters:

B – matrix [[b11, b12, …, b1m], [b21, b22, …, b2m], … [bn1, bn2, …, bnm]]

Raises:

numpy.linalg.LinAlgError – singular matrix

## BandedMatrixLU Class¶

class ezdxf.math.linalg.BandedMatrixLU(A: Matrix, m1: int, m2: int)

Represents a LU decomposition of a compact banded matrix.

upper

Upper triangle

lower

Lower triangle

m1

Lower band count, excluding main matrix diagonal

m2

Upper band count, excluding main matrix diagonal

index

Swapped indices

nrows

Count of matrix rows.

solve_vector(B: Iterable[float]) list[float]

Solves the linear equation system given by the banded nxn Matrix A . x = B, right-hand side quantities as vector B with n elements.

Parameters:

B – vector [b1, b2, …, bn]

Returns:

vector as list of floats

solve_matrix(B: List[List[float]] | ndarray[Any, dtype[float64]])

Solves the linear equation system given by the banded nxn Matrix A . x = B, right-hand side quantities as nxm Matrix B.

Parameters:

B – matrix [[b11, b12, …, b1m], [b21, b22, …, b2m], … [bn1, bn2, …, bnm]]

Returns:

matrix as `Matrix` object