Matrix#

class discopy.matrix.Matrix(array, *args, **kwargs)[source]#

Bases: Composable[int], Whiskerable, NamedGeneric['dtype']

A matrix is an array with natural numbers as dom and cod.

Summary

id([dom])

then(other)

tensor([other])

zero(dom, cod)

Returns the zero matrix of a given shape.

swap(left, right)

The matrix that swaps left and right dimensions.

transpose()

conjugate()

dagger()

map(func[, dtype])

round([decimals])

Rounds the entries of a matrix up to a number of decimals.

copy(x, n)

discard(x)

merge(x, n)

basis(x, i)

The i-th basis vector of dimension x.

repeat()

The reflexive transitive closure of a boolean matrix.

trace([n, left])

The trace of a Boolean matrix, computed with Matrix.repeat().

lambdify(*symbols[, dtype])

subs(*args)

grad(var, **params)

Gradient with respect to variables.

Note

The class Matrix[dtype] has arrays with entries in any given dtype. For example:

>>> Matrix[complex].id(1)
Matrix[complex]([1.+0.j], dom=1, cod=1)
>>> assert Matrix[complex].id(1) != Matrix[float].id(1)

The default data type is determined by underlying array datastructure of the backend used. An array is initialised with array as parameter and the dtype of the Matrix object is the data type of this array. >>> import numpy as np >>> assert Matrix([1, 0], dom=1, cod=2).dtype == np.int64 >>> assert Matrix([0.5, 0.5], dom=1, cod=2).dtype == np.float64 >>> assert Matrix([0.5j], dom=1, cod=1).dtype == np.complex128

The data type needs to have the structure of a rig (riNg with no negatives) i.e. with methods __add__ and __mul__ as well as an __init__ that can accept both 0 and 1 as input.

Examples

>>> m = Matrix([0, 1, 1, 0], 2, 2)
>>> v = Matrix([0, 1], 1, 2)
>>> v >> m >> v.dagger()
Matrix[int64]([0], dom=1, cod=1)
>>> m + m
Matrix[int64]([0, 2, 2, 0], dom=2, cod=2)
>>> assert m.then(m, m, m, m) == m >> m >> m >> m >> m

The monoidal product for Matrix is the direct sum:

>>> x = Matrix([2, 4], 2, 1)
>>> x.array
array([[2],
       [4]])
>>> x @ x
Matrix[int64]([2, 0, 4, 0, 0, 2, 0, 4], dom=4, cod=2)
>>> (x @ x).array
array([[2, 0],
       [4, 0],
       [0, 2],
       [0, 4]])
cast(dtype)[source]#

Cast a matrix to a given dtype.

Parameters:

dtype (type) – The target datatype.

Return type:

Matrix

Example

>>> assert Matrix.id().cast(bool) == Matrix[bool].id()
is_close(other, rtol=1e-08, atol=1e-08)[source]#

Whether a matrix is numerically close to an other.

Parameters:
  • other (Matrix) – The other matrix with which to check closeness.

  • rtol (float) – The relative tolerance parameter (see Notes). Default value for results of order unity is 1.e-5

  • atol (float) – The absolute tolerance parameter (see Notes). Default value for results of order unity is 1.e-8

Return type:

bool

Notes: (taken from np.isclose documentation)

For finite values, isclose uses the following equation to test whether two floating point values are equivalent.

absolute(a - b) <= (atol + rtol * absolute(b))

Unlike the built-in math.isclose, the above equation is not symmetric in a and b – it assumes b is the reference value – so that isclose(a, b) might be different from isclose(b, a).

Furthermore, the default value of atol is not zero, and is used to determine what small values should be considered close to zero. The default value is appropriate for expected values of order unity: if the expected values are significantly smaller than one, it can result in false positives.

atol should be carefully selected for the use case at hand. A zero value for atol will result in False if either a or b is zero.

isclose is not defined for non-numeric data types. bool is considered a numeric data-type for this purpose

classmethod zero(dom, cod)[source]#

Returns the zero matrix of a given shape.

Examples

>>> assert Matrix.zero(2, 2) == Matrix([0, 0, 0, 0], 2, 2)
Parameters:
  • dom (int) –

  • cod (int) –

Return type:

Matrix

classmethod swap(left, right)[source]#

The matrix that swaps left and right dimensions.

Parameters:
  • left (int) – The left dimension.

  • right (int) – The right dimension.

Return type:

Matrix

Example

>>> Matrix.swap(1, 1)
Matrix[int64]([0, 1, 1, 0], dom=2, cod=2)
>>> Matrix.swap(2,1)
Matrix[int64]([0, 1, 0, 0, 0, 1, 1, 0, 0], dom=3, cod=3)
classmethod braid(left, right)#

The matrix that swaps left and right dimensions.

Parameters:
  • left (int) – The left dimension.

  • right (int) – The right dimension.

Return type:

Matrix

Example

>>> Matrix.swap(1, 1)
Matrix[int64]([0, 1, 1, 0], dom=2, cod=2)
>>> Matrix.swap(2,1)
Matrix[int64]([0, 1, 0, 0, 0, 1, 1, 0, 0], dom=3, cod=3)
round(decimals=0)[source]#

Rounds the entries of a matrix up to a number of decimals.

Return type:

Matrix

classmethod basis(x, i)[source]#

The i-th basis vector of dimension x.

Parameters:
  • x (int) – The dimension of the basis vector.

  • i (int) – The index of the basis vector.

Return type:

Matrix

Example

>>> Matrix.basis(4, 2)
Matrix[int64]([0, 0, 1, 0], dom=1, cod=4)
repeat()[source]#

The reflexive transitive closure of a boolean matrix.

Example

>>> Matrix[bool]([0, 1, 1, 0], 2, 2).repeat()
Matrix[bool]([True, True, True, True], dom=2, cod=2)
Return type:

Matrix

trace(n=1, left=False)[source]#

The trace of a Boolean matrix, computed with Matrix.repeat().

Parameters:

n – The number of dimensions to trace.

Return type:

Matrix

Example

>>> assert Matrix[bool].swap(1, 1).trace() == Matrix[bool].id(1)
grad(var, **params)[source]#

Gradient with respect to variables.

Return type:

Matrix

factory#

alias of Matrix