Tensor#

class discopy.tensor.Tensor(array, *args, **kwargs)[source]#

Bases: Matrix

A tensor is a Matrix with dimensions as domain and codomain and the Kronecker product as tensor.

Parameters:
  • inside – The array inside the tensor.

  • dom (T) – The domain dimension.

  • cod (T) – The codomain dimension.

Summary

id([dom])

then([other])

tensor([other])

dagger()

cups(left, right)

caps(left, right)

swap(left, right)

spiders(n_legs_in, n_legs_out, typ[, phase])

The tensor of interleaving spiders.

transpose([left])

Returns the diagrammatic transpose.

conjugate([diagrammatic])

Returns the conjugate of a tensor.

round([decimals])

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

subs(*args)

grad(var, **params)

Gradient with respect to variables.

jacobian(*variables, **params)

Jacobian with respect to variables.

Examples

>>> m = Tensor([0, 1, 1, 0], Dim(2), Dim(2))
>>> v = Tensor([0, 1], Dim(1), Dim(2))
>>> v >> m >> v.dagger()
Tensor[int64]([0], dom=Dim(1), cod=Dim(1))

Notes

Tensors can have sympy symbols as free variables.

>>> from sympy import Expr
>>> from sympy.abc import phi, psi
>>> v = Tensor[Expr]([phi, psi], Dim(1), Dim(2))
>>> d = v >> v.dagger()
>>> assert v >> v.dagger() == Tensor[Expr](
...     [phi * phi.conjugate() + psi * psi.conjugate()], Dim(1), Dim(1))

These can be substituted and lambdifed.

>>> v.subs(phi, 0).lambdify(psi, dtype=int)(1)
Tensor[int]([0, 1], dom=Dim(1), cod=Dim(2))

We can also use jax.numpy using backend().

>>> with backend('jax'):
...     f = lambda *xs: d.lambdify(phi, psi, dtype=float)(*xs).array
...     import jax
...     assert jax.grad(f)(1., 2.) == 2.
classmethod spiders(n_legs_in, n_legs_out, typ, phase=None)[source]#

The tensor of interleaving spiders.

Parameters:
  • n_legs_in (int) – The number of legs in for each spider.

  • n_legs_out (int) – The number of legs out for each spider.

  • typ (Dim) – The type of the spiders.

Return type:

Tensor

classmethod copy(x, n)[source]#

Constructs spiders of dimension x with one leg in and n legs out.

Parameters:
  • x (Dim) – The type of the spiders.

  • n (int) – The number of legs out for each spider.

Return type:

Tensor

Example

>>> from discopy import markov
>>> n = markov.Ty('n')
>>> F = Functor(ob={n: Dim(2)}, ar={}, dom=markov.Category())
>>> assert F(markov.Copy(n, 2)) == Tensor[int].copy(Dim(2), 2)\
...     == Tensor[int]([1, 0, 0, 0, 0, 0, 0, 1], Dim(2), Dim(2, 2))
transpose(left=False)[source]#

Returns the diagrammatic transpose.

Note

This is not the same as the algebraic transpose for non-atomic dims.

Return type:

Tensor

property l: Tensor#

Returns the diagrammatic transpose.

Note

This is not the same as the algebraic transpose for non-atomic dims.

property r: Tensor#

Returns the diagrammatic transpose.

Note

This is not the same as the algebraic transpose for non-atomic dims.

conjugate(diagrammatic=True)[source]#

Returns the conjugate of a tensor.

Parameters:

diagrammatic (bool, default: True) – Whether to use the diagrammatic or algebraic conjugate.

Return type:

Tensor

classmethod zero(dom, cod)[source]#

Returns the zero tensor of a given shape.

Examples

>>> assert Tensor.zero(Dim(2), Dim(2))\
...     == Tensor([0, 0, 0, 0], Dim(2), Dim(2))
Parameters:
Return type:

Tensor

jacobian(*variables, **params)[source]#

Jacobian with respect to variables.

Parameters:

variables (list[sympy.Symbol]) – The list of variables to differentiate.

Returns:

tensor – with tensor.dom == self.dom and tensor.cod == Dim(len(variables)) @ self.cod.

Return type:

Tensor

Examples

>>> from sympy import Expr
>>> from sympy.abc import x, y, z
>>> vector = Tensor[Expr]([x ** 2, y * z], Dim(1), Dim(2))
>>> vector.jacobian(x, y, z)
Tensor[Expr]([2*x, 0, 0, z, 0, y], dom=Dim(1), cod=Dim(3, 2))
factory#

alias of Tensor