CMap#

class discopy.tensor.CMap(dom, cod, boxes, edges, offsets=None, loops=())[source]#

Bases: discopy.frobenius.CMap

A tensor combinatorial map is a tensor network stored as a combinatorial map, whose structure is Einstein notation: boxes are tensors, the 2-cycles of the edges involution are the summed indices and the boundary ports are the free indices.

Swaps, cups and caps become wiring while spiders stay as boxes, so that every wire has exactly two ends.

Example

>>> vector = Box('vector', Dim(1), Dim(2), [0, 1])
>>> assert (vector >> vector[::-1]).to_map().eval().array == 1
>>> with backend('jax'):
...     import jax, jax.numpy as jnp
...     b = lambda x: Box[float]('v', Dim(1), Dim(2), x * jnp.ones(2))
...     f = lambda x: (b(x) >> b(x)[::-1]).to_map().eval().array
...     assert jax.grad(f)(1.) == 4.
Parameters:
  • dom (C0) –

  • cod (C0) –

  • boxes (tuple[Box, ...]) –

  • edges (Iterable[int]) –

  • offsets (tuple[int | None, ...] | None) –

  • loops (tuple[C0, ...]) –

category#

alias of Diagram

eval(dtype=None, optimize='greedy', **params)#

Evaluate a tensor network as a Tensor: call the Functor that sends each box to its array.

Parameters:
  • dtype (type) – The datatype for spiders and the result, inferred from the boxes by default.

  • optimize – The contraction path, passed verbatim to the backend einsum.

  • params – Any other optional parameter of the backend einsum method, passed verbatim.

Return type:

Tensor

Examples

>>> vector = Box('vector', Dim(1), Dim(2), [0, 1])
>>> assert (vector >> vector[::-1]).eval().array == 1
>>> assert (vector >> vector[::-1]).eval(
...     optimize="optimal").array == 1