The Matrix Types — Matrix and FrozenMatrix

Constructing matrix objects

The constructors for both classes work the same way:

class Matrix(data[, shape, *, default])
class FrozenMatrix(data[, shape, *, default])

Return a new Matrix or FrozenMatrix object, whose cell values are taken from data.

Matrices can be created in several different ways:

  • From an existing Matrix or FrozenMatrix instance: Matrix(m).

  • From a sequence of sequences: Matrix([[1, 2, 3], [4, 5, 6]], default=0).

  • From a simple sequence: Matrix([1, 2, 3, 4, 5, 6], shape=(2, 3), default=0).

When constructing a new Matrix or FrozenMatrix object from an existing Matrix or FrozenMatrix instance, both the shape and default arguments are optional. If they are not specified, they will be copied over from the matrix passed as data. If shape is specified, the new matrix will be reshaped by internally calling resize() to resize the matrix. If default is specified this will be used as the new default value, but cells with a value equal to the default (new or old) already in data will never be altered.

When constructing a new Matrix or FrozenMatrix object from a sequence of sequences, it is assumed that these are in the form of a sequence of rows, with each row being a sequence of column values. The shape argument is optional, and if not specified will be inferred based on the number of ‘row-sequences’ and the longest sequence of ‘column-items’. For instance, Matrix([[1, 2, 3], [], [1, 2, 3, 4]], default=0) will yield a matrix object with 3 rows and 4 columns. If shape is specified and does not match the inferred size, then the data is padded with default where too few items are found, while items exceeding the expected number are ignored. The default argument is obligatory because there is no reliable way of inferring an appropriate default value from a regular sequence.

When constructing a new Matrix or FrozenMatrix object from a ‘flat’ sequence, both the shape and default arguments are obligatory as they cannot be inferred from a regular sequence. The values taken from data are used to fill the matrix row-wise. Left-over values in data are ignored, and any remaining cells are padded with default. This offers a very useful pattern for constructing matrices with a single value by passing an empty sequence as data, e.g. to construct a 3x3 zero-matrix, we can call Matrix([], (3, 3), default=0).

Note that to construct matrix objects containing a sequence type (including other matrices), you must either construct them from another matrix or as a sequence of sequences, because they would never be interpreted as a ‘flat’ sequence upon inspection. For instance, to create a 2x1 matrix containing two-tuples, use Matrix([[("a", "b")],[("c", "d")]], default=tuple()).

Examples:
Constructing matrix objects from a flat sequence
from matrices import Matrix, FrozenMatrix

# Matrices with 2 rows, 3 columns, and all cells filled with '0'
a = Matrix([], (2, 3), default=0)
b = FrozenMatrix([], (2, 3), default=0)

# 2x2 matrices of the form
#    1  2
#    3  4
c = Matrix([1, 2, 3, 4], (2, 2), default=0)
d = FrozenMatrix(range(100), (2, 2), default=0)
Constructing matrix objects from sequences of sequences
from matrices import Matrix, FrozenMatrix

# 2x2 matrices of the form
#    1  2
#    3  4
a = Matrix([[1, 2], [3, 4]], default=0)  # The shape can be inferred
b = FrozenMatrix([[1, 2] [3, 4]], (2, 2), default=0)  # Explicit shape
Constructing matrix objects from other matrix objects
from matrices import Matrix, FrozenMatrix

# 2x2 matrices of the form
#    1  2
#    3  4
a = Matrix([[1, 2], [3, 4]], default=0)  # Construct mutable matrix
b = FrozenMatrix(a)  # Immutable copy of a
Parameters:
  • data (MatrixABC[~T] | Sequence[~T] | Sequence[Sequence[~T]]) – The data to be used to fill in the initial values of the matrix.

  • shape (tuple[int, int]) – The shape the matrix should have in the format (rows, cols). Obligatory if data is a flat sequence.

  • default (~T) – Keyword-only argument specifying the default value to be used for cells that otherwise have not been assigned any value. Also used to evaluate semantically whether a cell (or entire matrix) is interpreted as empty or not.

Return type:

Matrix[~T] | FrozenMatrix[~T]

Returns:

Returns a new Matrix or FrozenMatrix object.

Differences between Matrix and FrozenMatrix

The principal difference between Matrix and FrozenMatrix objects is that the former are mutable and the latter are immutable.

Whereas many methods on Matrix modify the matrix in-place and return the modified object itself, FrozenMatrix always returns a modified copy of itself instead.

In line with this, FrozenMatrix does not implement key-based assignment (e.g. m[0, 0] = 123) and in-place operands (e.g. m *= 3), because this is not compatible with the copy-on-modification approach.

If you want to write code which is compatible with both Matrix and FrozenMatrix, it is thus important to always implicitly assign your results. For instance:

def good(m: MatrixABC) -> None:
    # This will work with both Matrix and FrozenMatrix
    m = m.resize(4, 4)
    print(m[3, 3])

def bad(m: MatrixABC) -> None:
    # This will not work with FrozenMatrix
    m.resize(4, 4)
    print(m[3, 3])

a = Matrix([1, 2, 3, 4, 5, 6], (3, 3), default=0)
b = FrozenMatrix(a)
good(a) # Success: prints '0'
bad(a)  # Success: prints '0'
good(b) # Success: prints '0'
bad(b)  # Failure: raises IndexError

Important

Immutability is imperfect!

While FrozenMatrix does not provide any public functionality that would alter a specific instance of FrozenMatrix, and all operations affecting the matrix’s shape or values result in copies, Python itself does not offer any mechanism to truly prevent user code from modifying the internals of an object (e.g. by accessing and modifying the internal data structure directly).

This means that immutability with FrozenMatrix can be assumed, but cannot be guaranteed, because user code could potentially attempt to modify the internals of the object, even if that is very poor practice and to be discouraged in the strongest terms.

You should never write code that modifies the internals (any attributes whose name starts with an underscore) on an already-instantiated object. If you ever have the need to access or modify the internals of a matrix object, you should subclass MatrixABC, Matrix, or FrozenMatrix instead, and retain that functionality within your subclass, so that assurances about mutability/immutability can be maintained for all matrix objects.

Basic properties of matrix objects

bool(m)

Return True iff any of the cells of the matrix contain a value other than the current default value.

Always returns False for matrices with a zero dimension (i.e. matrices with the shapes 0x0, nx0, and 0xn).

For the inverse of bool(m), see m.empty().

Note

Note that this behaviour may lead to two matrices with the same values comparing as equal, while one of these matrices evaluates as True and the other as False, namely if they have different default values.

Example:
a = Matrix([1, 1, 1, 1], (2, 2), default=0)
b = Matrix([1, 1, 1, 1], (2, 2), default=1)

a == b  # Evaluates to True, because both matrices have the same values
bool(a) # Evaluates to True, because at least one of the values is not 0
bool(b) # Evaluates to False, because all the values are 1 (the default)
Return type:

bool

property m.default

The current default value of the matrix.

Read-only on immutable FrozenMatrix objects, read-write on mutable Matrix objects.

Altering the default will never affect the data already present in a matrix, it will only affect value comparisons and new values inserted after the default was modified. For example:

>>> a = Matrix([], (3, 3), default=0)
>>> a.empty()
True
>>> a.default = 1
>>> a.empty()
False
>>> a.resize(4, 4)
>>> print(a)
     0  1  2  3
  ┌             ┐
0 │  0  0  0  1 │
1 │  0  0  0  1 │
2 │  0  0  0  1 │
3 │  1  1  1  1 │
  └             ┘

To change the default value on immutable FrozenMatrix objects, you must create a new FrozenMatrix object with the default property overwritten. For example:

>>> a = FrozenMatrix([], (3, 3), default=0)
>>> bool(a)
False
>>> b = FrozenMatrix(a, default=1)  # a with the default overwritten
>>> bool(b)
True
Type:

~T

m.empty()

Return True iff all of the cells of the matrix are equal to the current default value, or the matrix has a zero dimension (i.e. matrices with the shapes 0x0, nx0, and 0xn). Return False otherwise.

For the inverse of m.empty(), see bool(m).

Return type:

bool

len(m)

Return the number of items (cells) in the matrix. This is always the product of the number of rows and the number of columns, e.g. for a 5x10 matrix this would be 5 * 10 = 50.

Return type:

int

property m.shape

The current shape of the matrix in the form (rows, cols).

Read-only on immutable FrozenMatrix objects, read-write on mutable Matrix objects.

To alter the shape on FrozenMatrix objects, use m.resize() or make a new object with the shape property overwritten instead.

Type:

tuple[int, int]

Row and column manipulation

Shape modifications, such as the addition, removal, or swapping of rows or columns are a mainstay when working with matrices. The matrix-types package provides a number of convenient functions to accomplish this.

m.appendcol(data)

Append a column with values data to the right of the matrix.

Parameters:

data (Sequence[~T]) – The values to be inserted in the new column.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

m.appendrow(data)

Append a row with values data to the bottom of the matrix.

Parameters:

data (Sequence[~T]) – The values to be inserted in the new row.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

m.flip(*[, by])

Flip the order a matrix’s rows or columns.

If by is "row" (the default), then the order of the rows in the matrix will be flipped (i.e. reversed). If by is "col", then the order of the columns in the matrix will be flipped.

Examples:
Flipping rows
m = FrozenMatrix([[1, 1], [2, 2]], default=0)
print(m)
# Output:
#      0  1
#    ┌      ┐
#  0 │ 1  1 │
#  1 │ 2  2 │
#    └      ┘
print(m.flip())
# Output:
#      0  1
#    ┌      ┐
#  0 │ 2  2 │
#  1 │ 1  1 │
#    └      ┘
Flipping columns
m = FrozenMatrix([[1, 2], [1, 2]], default=0)
print(m)
# Output:
#      0  1
#    ┌      ┐
#  0 │ 1  2 │
#  1 │ 1  2 │
#    └      ┘
print(m.flip(by="col"))
# Output:
#      0  1
#    ┌      ┐
#  0 │ 2  1 │
#  1 │ 2  1 │
#    └      ┘
Parameters:

by (RowColT) – One of the literals "row" (the default) or "col", specifies whether the matrix should be flipped row-wise or column-wise.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a flipped copy of self.

m.fliph()

Alias for m.flip(by="col").

m.flipv()

Alias for m.flip(by="row").

m.insertcol(index, data)

Insert a column with values data to the left of the column referenced by index.

Parameters:
  • index (int) – The column index before which the new column should be inserted.

  • data (Sequence[~T]) – The values to be inserted in the new column.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

m.insertrow(index, data)

Insert a row with values data to the top of the row referenced by index.

Parameters:
  • index (int) – The row index before which the new row should be inserted.

  • data (Sequence[~T]) – The values to be inserted in the new row.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

m.prependcol(data)

Prepend a column with values data at the left of the matrix.

Parameters:

data (Sequence[~T]) – The values to be inserted in the new column.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

m.prependrow(data)

Prepend a row with values data at the top of the matrix.

Parameters:

data (Sequence[~T]) – The values to be inserted in the new row.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

m.removecol(index)

Remove the column at index.

Caution

The column is removed completely from the matrix, and the matrix’s shape will be altered. Calling this function does not merely reset the values of items in the targeted column to their default!

Parameters:

index (int) – The index of the column to be removed.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

m.removerow(index)

Remove the row at index.

Caution

The row is removed completely from the matrix, and the matrix’s shape will be altered. Calling this function does not merely reset the values of items in the targeted row to their default!

Parameters:

index (int) – The index of the row to be removed.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

m.resize(rows, cols)
m.resize(shape)

Grow or shrink a matrix.

Grows or shrinks the matrix depending on whether the new shape’s rows or cols are less than or greater than the current row or column count. Has no effect on the shape if they match the current row and column count.

Where the new shape has fewer rows or columns the values from these will be lost. Where the new shape has additional rows or columns, these will be populated with m.default.

Parameters:
  • shape (tuple[int, int]) – Positional-only argument specifying the shape of the resized matrix in the form (rows, cols).

  • rows (int) – The number of rows the matrix should have after resizing.

  • cols (int) – The number of columns the matrix should have after resizing.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

m.swapcols(a_index, b_index)

Swap the two columns with indices a_index and b_index.

Example:
>>> a = Matrix([[0, 1, 2], [0, 1, 2]], default=0)
>>> print(a)
    0  1  2
  ┌         ┐
0 │ 0  1  2 │
1 │ 0  1  2 │
  └         ┘
>>> print(a.swapcols(0, 2))
    0  1  2
  ┌         ┐
0 │ 2  1  0 │
1 │ 2  1  0 │
  └         ┘
Parameters:
  • a_index (int) – The column index of the first column to be swapped.

  • b_index (int) – The column index of the second column to be swapped.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

m.swaprows(a_index, b_index)

Swap the two rows with indices a_index and b_index.

Example:
>>> a = Matrix([[0, 0], [1, 1], [2, 2]], default=0)
>>> print(a)
    0  1
  ┌      ┐
0 │ 0  0 │
1 │ 1  1 │
2 │ 2  2 │
  └      ┘
>>> print(a.swaprows(0, 2))
    0  1
  ┌      ┐
0 │ 2  2 │
1 │ 1  1 │
2 │ 0  0 │
  └      ┘
Parameters:
  • a_index (int) – The row index of the first row to be swapped.

  • b_index (int) – The row index of the second row to be swapped.

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

m.transpose()

Transpose the rows and columns of the matrix.

In a transposed matrix, the first row is converted to the first column, the second row is converted to the second column, and so on. Transposing a matrix twice in a row always returns it to its original form.

This turns a matrix of the form \(\begin{bmatrix}1 & 2 & 3\\4 & 5 & 6\end{bmatrix}\) into a matrix of the form \(\begin{bmatrix}1 & 4\\ 2 & 5\\3 & 6\end{bmatrix}\).

Return type:

Self

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

Accessing values in a matrix

m.copy()

Return a shallow copy of the matrix.

Return type:

Self

Returns:

Returns a shallow copy of self.

m.get(row, col)
m.get(key)
m[row, col]
m[key]

Access one or more values in the matrix object.

Where row and col are single integers giving a row/column index (or a key is a tuple specifying a single row and a column index), return or set the value of the cell indexed by (row, col).

Example:

Accessing individual cell values
a = Matrix([[1, 2, 3], [4, 5, 6]], default=0)
b = FrozenMatrix(a)
print(a[0, 0]) # print 1
print(b[1, 2]) # print 6
a[0, 0] = 99   # set first cell of a to 99
print(a[0, 0]) # print 99
b[0, 0] = 99   # TypeError: 'FrozenMatrix' object does not support item assignment

Where either of the row or col indices are specified as a slice or a tuple of indices, return or set the values of a submatrix as indicated by the intersection of the selected row and col indices.

When assigning to a matrix using a slice or multiple indeces, the assigned object must be a sequence of an equal length to the matrix object returned by the equivalent access call, and values will be over-written by row-wise assignment.

Examples:

Accessing a subset of cells with arbitrary indices
a = Matrix([[1, 2, 3], [4, 5, 6]], default=0)
print(a)
#     0  1  2
#   ┌         ┐
# 0 │ 1  2  3 │
# 1 │ 4  5  6 │
#   └         ┘
print(a[0, (0, 2)]) # First row, first and last column
#     0  1
#   ┌      ┐
# 0 │ 1  3 │
#   └      ┘
a[0, (0, 2)] = (11, 13)
print(a)
#      0  1   2
#   ┌           ┐
# 0 │ 11  2  13 │
# 1 │  4  5   6 │
#   └           ┘
Accessing a subset of cells with slices
a = Matrix([[1, 2, 3], [4, 5, 6]], default=0)
print(a)
#     0  1  2
#   ┌         ┐
# 0 │ 1  2  3 │
# 1 │ 4  5  6 │
#   └         ┘
print(a[0, 1:3]) # First row, second and third column
#     0  1
#   ┌      ┐
# 0 │ 2  3 │
#   └      ┘
a[0, 1:3] = (12, 13)
print(a)
#      0   1   2
#   ┌            ┐
# 0 │  1  12  13 │
# 1 │  4   5   6 │
#   └            ┘

As with other sequence types supporting slices, m[:, :] can be used to produce a shallow copy of the matrix object.

Note

If using slice assignment to assign values from one matrix object to another, you must assign m.values() rather than m directly, otherwise what is assigned are the keys of the other matrix, not the values.

Example:

a = Matrix([], shape=(4, 4), default=0)
b = Matrix([], shape=(4, 4), default=1)
a[1:3, 0:3] = b[1:3, 0:3]
print(a)
#          0       1       2  3
#   ┌                           ┐
# 0 │      0       0       0  0 │
# 1 │ (0, 0)  (0, 1)  (0, 2)  0 │
# 2 │ (1, 0)  (1, 1)  (1, 2)  0 │
# 3 │      0       0       0  0 │
#   └                           ┘
a[1:3, 0:3] = b[1:3, 0:3].values()
print(a)
#     0  1  2  3
#   ┌            ┐
# 0 │ 0  0  0  0 │
# 1 │ 1  1  1  0 │
# 2 │ 1  1  1  0 │
# 3 │ 0  0  0  0 │
#   └            ┘
Parameters:
  • key (tuple[IndexT, IndexT]) – A tuple of row and col indeces.

  • row (IndexT) – The row index for the cell(s) to retreive, can be an integer to refer to a single row, a slice to refer to a subset of rows, or a tuple of row indices to select any arbitrary number of rows.

  • col (IndexT) – The column index for the cell(s) to retreive, can be an integer to refer to a single column, a slice to refer to a subset of columns, or a tuple of column indices to select any arbitrary number of columns.

Return type:

~T | Matrix[~T] | FrozenMatrix[~T]

Returns:

Returns the value of the cell specified by row, col if both of these refer to a single cell (i.e. both row and cell are single integers), otherwise returns a new Matrix or FrozenMatrix object containing the selected rows and column (possibly 0x0, nx0 or 0xn), following standard Python slice logic and intersecting the slices where appropriate.

m.items(*[, by])

Return a list of the matrix’s items ((key, value) pairs).

The key of each returned pair itself is a tuple with row and column indices for the item. This allows for two different ways of destructuring the list returned by m.items():

m = Matrix([[1, 2], [3, 4]], default=0)
for key, value in m.items():
   print(f"m at {key} has the value {value}")
# m at (0, 0) has the value 1
# m at (0, 1) has the value 2
# m at (1, 0) has the value 3
# m at (1, 1) has the value 4
for (row, col), value in m.items():
   print(f"m[{row}, {col}] has the value {value}")
# m[0, 0] has the value 1
# m[0, 1] has the value 2
# m[1, 0] has the value 3
# m[1, 1] has the value 4

Note that, since m[(row, col)] is equivalent to m[row, col] (the latter being syntactic sugar for the former), it is not necessary to destructure the key unless you care about the individual values of the row or column indices.

See also m.asdict() for a method which returns the same data as a dictionary rather than a list of tuples.

Parameters:

by (RowColT) – One of the literals "row" (the default) or "col", specifies whether the list of key-value pairs should be constructed by row-wise or column-wise iteration of the matrix.

Return type:

list[tuple[tuple[int, int], ~T]]

Returns:

Returns a list of tuples where the first member of each tuple is a key tuple (a tuple with indices of the form (row, col)) and the second member of the tuple is the value of the cell indexed by that key. The list is ordered row-wise or column-wise depending on by.

m.keys(*[, by])

Return a list of the matrix’s keys ((row, col) pairs).

Parameters:

by (RowColT) – One of the literals "row" (the default) or "col", specifies whether the list of keys should be constructed by row-wise or column-wise iteration of the matrix.

Return type:

list[tuple[int, int]]

Returns:

Returns a list of tuples with all the keys (aka row and column indices) of the matrix, ordered row-wise or column-wise depending on by. Each tuple has the form (row, col).

m.values(*[, by])

Return a list of the matrix’s values.

Note that, unlike Python’s native dictionaries, Matrix/FrozenMatrix does not use view objects, but returns lists instead. This means that the results of m.values() will compare True if the list of values and their order is identical, where the results of dict.values() would compare False even to itself.

Parameters:

by (RowColT) – One of the literals "row" (the default) or "col", specifies whether the list of values should be constructed by row-wise or column-wise iteration of the matrix.

Return type:

list[~T]

Returns:

Returns a list of all the cell values in the matrix, ordered row-wise or column-wise depending on by.

submatrix(rows, cols)

Get a copy of the matrix object containing only the intersection of rows and cols.

Example:
>>> a = Matrix([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], default=0)
>>> print(a)
     0   1   2   3
   ┌               ┐
 0 │ 1   2   3   4 │
 1 │ 5   6   7   8 │
 2 │ 9  10  11  12 │
   └               ┘
>>> print(a.submatrix(0, 0)) # Selects a single cell
     0
   ┌   ┐
 0 │ 1 │
   └   ┘
>>> print(a.submatrix((0, 2), (0, 1, 2))) # rows 0 and 2, columns 0, 1 and 2
     0   1   2
   ┌           ┐
 0 │ 1   2   3 │
 1 │ 9  10  11 │
   └           ┘
Parameters:
  • rows (IndexT) – The row indices to select for the submatrix. Can be an integer for a single row, a slice to refer to a subset of rows, or a tuple of row indices to select any arbitrary number of rows.

  • cols (IndexT) – The column indices to select for the submatrix. Can be an integer for a single column, a slice to refer to a subset of columns, or a tuple of column indices to select any arbitrary number of columns.

Return type:

Matrix[~T] | FrozenMatrix[~T]

Returns:

A new matrix object of the same type as the original, containing only the intersection of the specified rows and cols.

Iterating over matrices

m.foreach(func[, *args, **kwargs])

Apply func to each cell in the matrix.

Any additional args and kwargs will be passed as arguments to func.

The return value of func will be ignored. To mutate the values of each cell in-place, use m.map() instead.

m.foreach() always iterates row-wise.

Example:
>>> m = Matrix([[1, 2, 3], [4, 5, 6]], default=0)
>>> m.foreach(lambda x: print(x) if x % 2 == 0 else ...)
2
4
6
Parameters:
  • func (Callable[..., Any]) – A callable accepting at least one argument (namely the value of each cell as the matrix is iterated over).

  • args (Any) – Optional positional arguments to be passed to func.

  • kwargs (Any) – Optional keyword arguments to be passed to func.

Return type:

Self

Returns:

Always returns self, even in the case of an immutable FrozenMatrix object, since the matrix object itself is never modified by m.foreach().

iter(m)

Return an iterator object iterating over the row and column indices of the matrix object (not the cell values directly). The iterator always iterates over the matrix row-wise.

Example:
>>> m = Matrix([[1, 2, 3], [4, 5, 6]], default=0)
>>> for row, col in iter(m):
...     if m[row, col] % 2 == 0:
...         print(f"{m[row, col]} is even")
...     else:
...         print(f"{m[row, col]} is odd")
...
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
Parameters:
  • func (Callable[..., ~T]) – A callable accepting at least one argument (namely the value of each cell as the matrix is iterated over) and returning a value compatible with the type of the matrix object.

  • args (Any) – Optional positional arguments to be passed to func.

  • kwargs (Any) – Optional keyword arguments to be passed to func.

Return type:

Self

Return type:

Iterator

Returns:

An iterator over tuples of row and column indices.

m.map(func[, *args, **kwargs])

Apply func to each cell in the matrix and store the return value of func as the new cell value.

Any additional args or kwargs passed after func will be passed as parameters to func.

This will mutate the values of each cell in-place based on the return value of func. To apply func without affecting the values store in the matrix, use m.foreach() instead.

Returns:

Mutable Matrix objects return self, immutable FrozenMatrix objects return a modified copy of self.

Common operations on matrices

value in m

Return True if m has a value value.

Important

The semantics of the in statement with matrix objects are those of interables like Python’s native list type, which look up the values stored in the object.

They are not those of the dict type because the keys are strictly numerical, so that you can always check whether a key is within the matrix’s range by comparing the value to m.shape.

value not in m

Equivalent to not value in m.

m is other

Return True if and only if m and other are references to the exact same object.

This will return False for identical but independent Matrix/FrozenMatrix objects, which is especially important to keep in mind when attempting to compare the objects returned by method calls on FrozenMatrix objects, as these will not be the same object if the method might have modified the matrix, whereas they will be the same (modified) object on Matrix instances.

m == other

Return True if m and other are matrices of the same shape which contain the same values.

m.matadd(other)
m + other

Add the values of other to the values of m.

The values of other are added to the values of m with the same key (row and column index). The other matrix must have the same shape as the matrix to which it is added.

For an in-place variant see m.imatadd().

Example:
>>> m1 = Matrix([], shape=(2, 2), default=0)
>>> m2 = FrozenMatrix([[1, 2], [3, 4]], default=0)
>>> print(m1 + m2)
#     0  1
#   ┌      ┐
# 0 │ 1  2 │
# 1 │ 3  4 │
#   └      ┘
Parameters:

other (MatrixABC[~V]) – The Matrix or FrozenMatrix to be added to the matrix.

Return type:

Self | Matrix[~V] | FrozenMatrix[~V]

Returns:

Always returns a modified copy of self.

m.matmul(other)
m @ other

Multipy the matrices m and other.

The shape of other must be the inverse of the shape of m, e.g. if m.shape is (2, 5), then other.shape must be (5, 2). Matrix multiplication is not defined for matrices which do not satisfy this condition and an attempt to multiply matrices with incompatible shapes will raise a ValueError.

For an in-place variant see m.imatmul().

Parameters:

other (MatrixABC[~V]) – The Matrix or FrozenMatrix to

be multiplied with the matrix. :rtype: Self | Matrix[~V] | FrozenMatrix[~V] :returns: Always returns a modified copy of self.

m.matsub(other)
m - other

Subtract the values of other from the values of m.

The values of other are subtracted from the values of m with the same key (row and column index). The other matrix must have the same shape as the matrix from which it is subtracted.

For an in-place variant see m.imatsub().

Parameters:

other (MatrixABC[~V]) – The Matrix or FrozenMatrix to be subtracted from the matrix.

Return type:

Self | Matrix[~V] | FrozenMatrix[~V]

Returns:

Always returns a modified copy of self.

m.scaladd(scalar)
m + scalar

Add scalar to each value of the matrix m.

Note

The + operator cannot be used with scalars which are themselves matrix objects (e.g. when adding a matrix to each matrix in a matrix of matrices). Always use m.scaladd() if there is a chance that the scalar itself might be a matrix object.

For an in-place variant see m.iscaladd().

Example:
>>> m = FrozenMatrix([[1, 2], [3, 4]], default=0)
>>> print(m + 2)
#     0  1
#   ┌      ┐
# 0 │ 3  4 │
# 1 │ 5  6 │
#   └      ┘
Parameters:

scalar (~V) – The scalar value to be added to the matrix’s values.

Return type:

Self | Matrix[~V] | FrozenMatrix[~V]

Returns:

Always returns a modified copy of self.

m.scalmul(scalar)
m * scalar
scalar * m

Multipy each value in m with scalar.

For an in-place variant see m.iscalmul().

Parameters:

other (~V) – The scalar value to be multiplied with the matrix’s values.

Return type:

Self | Matrix[~V] | FrozenMatrix[~V]

Returns:

Always returns a modified copy of self.

m.scalsub(scalar)
m - scalar

Subtract scalar from each value of the matrix m.

Note

The - operator cannot be used with scalars which are themselves matrix objects (e.g. when subtracting a matrix from each matrix in a matrix of matrices). Always use m.scalsub() if there is a chance that the scalar itself might be a matrix object.

For an in-place variant see m.iscalsub().

Example:
>>> m = FrozenMatrix([[1, 2], [3, 4]], default=0)
>>> print(m - 1)
#     0  1
#   ┌      ┐
# 0 │ 0  1 │
# 1 │ 2  3 │
#   └      ┘
Parameters:

scalar (~V) – The scalar value to be subtracted from the matrix’s values.

Return type:

Self | Matrix[~V] | FrozenMatrix[~V]

Returns:

Always returns a modified copy of self.

In-place matrix operations

Most of the common matrix operations also implement an in-place variant for Matrix objects (but obviously not for FrozenMatrix objects). These modify the matrix in-place instead of returning a new Matrix or FrozenMatrix object.

Scalar in-place operations:

Matrix in-place operations:

See the respective regular operation. The semantics are the same except for the result being stored directly in the matrix m.

Converting matrices to other formats

m.aslist(*[, by])

Return the matrix’s values as a list of lists.

When by is "row" (the default), then the format of the returned list of lists is the same as would have been used to construct the matrix from a list of lists. If by is row, the list of lists returned is essentially that which would have been used to construct the transpose of the matrix.

See also m.values() which returns a flat list of the matrix’s values.

Example:
>>> m = Matrix([[1, 2, 3], [4, 5, 6]], default=0)
>>> m.aslist()
[[1, 2, 3], [4, 5, 6]]
>>> m.aslist(by="col")
[[1, 4], [2, 5], [3, 6]]
Parameters:

by (RowColT) – One of the literals "row" (the default) or "col", specifies whether the list of lists should be constructed by row-wise or column-wise iteration of the matrix.

Return type:

list[list[~T]]

Returns:

Returns a list of lists, with the sublists containing the values of the matrix either by column or by row, depending on by.

m.asdict()

Return the matrix’s values as a dictionary of {key: value} pairs.

Each key of the dictionary is a tuple of the row and column indices (a (row, col) pair), and the value the value of the corresponding cell with that key.

Example:
>>> m = Matrix([[1, 2, 3], [4, 5, 6]], default=0)
>>> m.asdict()
{(0, 0): 1, (0, 1): 2, (0, 2): 3, (1, 0): 4, (1, 1): 5, (1, 2): 6}
Return type:

dict[tuple[int, int], ~T]

Returns:

Returns a dictionary where they keys are tuples of indices of the form (row, col) and values the values of the cells with that index.

repr(m)

Return a potentially parseable string representation of the matrix.

The returned repr gives the matrix’s values in the form of a tuple of tuples. The returned string itself is valid python which can be used to recreate the matrix if and only if all the values in the matrix also have a repr which produces valid python.

Example:
>>> m = Matrix([[1, 2, 3], [4, 5, 6]], default=0)
>>> print(repr(m))
Matrix(((1, 2, 3),(4, 5, 6),), default=0)
Return type:

str

Returns:

A string representation of the matrix object.

str(m)

Return a string with a visual representation of the matrix.

Example:

>>> m = Matrix([[1, 2, 3], [4, 5, 6]], default=0)
>>> print(str(m))
     0  1  2
   ┌         ┐
 0 │ 1  2  3 │
 1 │ 4  5  6 │
   └         ┘
Return type:

str

Returns:

A string displaying the matrix.