# Linear Algebra¶

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

## Functions¶

`ezdxf.math.linalg.``gauss_jordan_solver`(A: IterableMatrixData, B: IterableMatrixData) → tuple[Matrix, Matrix]

Solves the linear equation system given by a nxn Matrix A . x = B, right-hand side quantities as nxm Matrix B by the Gauss-Jordan algorithm, which is the slowest of all, but it is very reliable. Returns a copy of the modified input matrix A and the result matrix x.

Internally used for matrix inverse calculation.

Parameters: A – matrix [[a11, a12, …, a1n], [a21, a22, …, a2n], [a21, a22, …, a2n], … [an1, an2, …, ann]] B – matrix [[b11, b12, …, b1m], [b21, b22, …, b2m], … [bn1, bn2, …, bnm]] 2-tuple of `Matrix` objects `ZeroDivisionError` – singular matrix
`ezdxf.math.linalg.``gauss_jordan_inverse`(A: Iterable[Iterable[float]]) → ezdxf.math.linalg.Matrix

Returns the inverse of matrix A as `Matrix` object.

Hint

For small matrices (n<10) is this function faster than LUDecomposition(m).inverse() and as fast even if the decomposition is already done.

Raises: `ZeroDivisionError` – singular matrix
`ezdxf.math.linalg.``gauss_vector_solver`(A: Iterable[Iterable[float]], B: Iterable[float]) → list[float]

Solves the linear equation system given by a nxn Matrix A . x = B, right-hand side quantities as vector B with n elements by the Gauss-Elimination algorithm, which is faster than the Gauss-Jordan algorithm. The speed improvement is more significant for solving multiple right-hand side quantities as matrix at once.

Reference implementation for error checking.

Parameters: A – matrix [[a11, a12, …, a1n], [a21, a22, …, a2n], [a21, a22, …, a2n], … [an1, an2, …, ann]] B – vector [b1, b2, …, bn] vector as list of floats `ZeroDivisionError` – singular matrix
`ezdxf.math.linalg.``gauss_matrix_solver`(A: Iterable[Iterable[float]], B: Iterable[Iterable[float]]) → ezdxf.math.linalg.Matrix

Solves the linear equation system given by a nxn Matrix A . x = B, right-hand side quantities as nxm Matrix B by the Gauss-Elimination algorithm, which is faster than the Gauss-Jordan algorithm.

Reference implementation for error checking.

Parameters: A – matrix [[a11, a12, …, a1n], [a21, a22, …, a2n], [a21, a22, …, a2n], … [an1, an2, …, ann]] B – matrix [[b11, b12, …, b1m], [b21, b22, …, b2m], … [bn1, bn2, …, bnm]] matrix as `Matrix` object `ZeroDivisionError` – singular matrix
`ezdxf.math.linalg.``tridiagonal_vector_solver`(A: IterableMatrixData, 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] list of floats `ZeroDivisionError` – singular matrix
`ezdxf.math.linalg.``tridiagonal_matrix_solver`(A: Iterable[Iterable[float]], B: Iterable[Iterable[float]]) → ezdxf.math.linalg.Matrix

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]] matrix as `Matrix` object `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: ezdxf.math.linalg.Matrix, m1: int, m2: int) → ezdxf.math.linalg.Matrix

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
`ezdxf.math.linalg.``freeze_matrix`(A: Union[Iterable[Iterable[float]], ezdxf.math.linalg.Matrix]) → ezdxf.math.linalg.Matrix

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

## Matrix Class¶

class `ezdxf.math.linalg.``Matrix`(items: Optional[Any] = None, shape: Optional[Tuple[int, int]] = None, matrix: Optional[List[List[float]]] = None)

Basic matrix implementation without any optimization for speed or memory usage. Matrix data is stored in row major order, this means in a list of rows, where each row is a list of floats. Direct access to the data is accessible by the attribute `Matrix.matrix`.

The matrix can be frozen by function `freeze_matrix()` or method `Matrix.freeze()`, than the data is stored in immutable tuples.

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
`nrows`

Count of matrix rows.

`ncols`

Count of matrix columns.

`shape`

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

static `reshape`(items: Iterable[float], shape: Tuple[int, int]) → ezdxf.math.linalg.Matrix

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

classmethod `identity`(shape: Tuple[int, int]) → ezdxf.math.linalg.Matrix

Returns the identity matrix for configuration shape.

`row`(index: int) → list[float]

Returns row index as list of floats.

`iter_row`(index: int) → Iterator[float]

Yield values of row index.

`col`(index: int) → list[float]

Return column index as list of floats.

`iter_col`(index: int) → Iterator[float]

Yield values of column index.

`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]
`iter_diag`(index: int) → Iterator[float]

Yield values of diagonal index, see also `diag()`.

`rows`() → List[List[float]]

Return a list of all rows.

`cols`() → List[List[float]]

Return a list of all columns.

`set_row`(index: int, items: Union[float, Sequence[float]] = 1.0) → None

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

`set_col`(index: int, items: Union[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: Union[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]

`append_row`(items: Sequence[float]) → None

Append a row to the matrix.

`append_col`(items: Sequence[float]) → None

Append a column to the matrix.

`swap_rows`(a: int, b: int) → None

Swap rows a and b inplace.

`swap_cols`(a: int, b: int) → None

Swap columns a and b inplace.

`transpose`() → ezdxf.math.linalg.Matrix

Returns a new transposed matrix.

`inverse`() → ezdxf.math.linalg.Matrix

Returns inverse of matrix as new object.

`determinant`() → float

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

`freeze`() → ezdxf.math.linalg.Matrix

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

`lu_decomp`() → ezdxf.math.linalg.LUDecomposition

Returns the LU decomposition as `LUDecomposition` object, a faster linear equation solver.

`__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, tolerance value for comparison is adjustable by the attribute `Matrix.abs_tol`.

`__add__`(other: Union[ezdxf.math.linalg.Matrix, float]) → ezdxf.math.linalg.Matrix

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

`__sub__`(other: Union[ezdxf.math.linalg.Matrix, float]) → ezdxf.math.linalg.Matrix

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

`__mul__`(other: Union[ezdxf.math.linalg.Matrix, float]) → ezdxf.math.linalg.Matrix

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

## LUDecomposition Class¶

class `ezdxf.math.linalg.``LUDecomposition`(A: Iterable[Iterable[float]])

Represents a LU decomposition matrix of A, raise `ZeroDivisionError` for a singular matrix.

This algorithm is a little bit faster than the Gauss-Elimination algorithm using CPython and much faster when using pypy.

The `LUDecomposition.matrix` attribute gives access to the matrix data as list of rows like in the `Matrix` class, and the `LUDecomposition.index` attribute gives access to the swapped row indices.

Parameters: A – matrix [[a11, a12, …, a1n], [a21, a22, …, a2n], [a21, a22, …, a2n], … [an1, an2, …, ann]] `ZeroDivisionError` – singular matrix
`nrows`

Count of matrix rows (and cols).

`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] vector as list of floats
`solve_matrix`(B: Iterable[Iterable[float]]) → ezdxf.math.linalg.Matrix

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]] matrix as `Matrix` object
`inverse`() → ezdxf.math.linalg.Matrix

Returns the inverse of matrix as `Matrix` object, raise `ZeroDivisionError` for a singular matrix.

`determinant`() → float

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

## BandedMatrixLU Class¶

class `ezdxf.math.linalg.``BandedMatrixLU`(A: ezdxf.math.linalg.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] vector as list of floats
`solve_matrix`(B: Iterable[Iterable[float]]) → ezdxf.math.linalg.Matrix

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]] matrix as `Matrix` object
`determinant`() → float

Returns the determinant of matrix.