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
orFrozenMatrix
object, whose cell values are taken from data.Matrices can be created in several different ways:
From an existing
Matrix
orFrozenMatrix
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
orFrozenMatrix
object from an existingMatrix
orFrozenMatrix
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 callingresize()
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
orFrozenMatrix
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
orFrozenMatrix
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 callMatrix([], (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:
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)
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
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
orFrozenMatrix
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)
, seem.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 asFalse
, 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 mutableMatrix
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 newFrozenMatrix
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). ReturnFalse
otherwise.For the inverse of
m.empty()
, seebool(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 mutableMatrix
objects.To alter the shape on
FrozenMatrix
objects, usem.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, immutableFrozenMatrix
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, immutableFrozenMatrix
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:
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 │ # └ ┘
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, immutableFrozenMatrix
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, immutableFrozenMatrix
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, immutableFrozenMatrix
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, immutableFrozenMatrix
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, immutableFrozenMatrix
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, immutableFrozenMatrix
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, immutableFrozenMatrix
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, immutableFrozenMatrix
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, immutableFrozenMatrix
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, immutableFrozenMatrix
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, immutableFrozenMatrix
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:
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:
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 │ # └ ┘
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 thanm
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
orFrozenMatrix
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 tom[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 ofm.values()
will compareTrue
if the list of values and their order is identical, where the results ofdict.values()
would compareFalse
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 bym.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, immutableFrozenMatrix
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 nativelist
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 tom.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 independentMatrix
/FrozenMatrix
objects, which is especially important to keep in mind when attempting to compare the objects returned by method calls onFrozenMatrix
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 onMatrix
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
orFrozenMatrix
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)
, thenother.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 aValueError
.For an in-place variant see
m.imatmul()
.- Parameters:
other (MatrixABC[~V]) – The
Matrix
orFrozenMatrix
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
orFrozenMatrix
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 usem.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 usem.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:
m.iscaladd(scalar)
,m += scalar
, seem.scaladd()
.m.iscalmul(scalar)
,m *= scalar
, seem.scalmul()
.m.iscalsub(scalar)
,m -= scalar
, seem.scalsub()
.
Matrix in-place operations:
m.imatadd(other)
,m += other
, seem.matadd()
.m.imatmul(other)
,m @= other
, seem.matmul()
.m.imatsub(other)
,m -= other
, seem.matsub()
.
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.