Bubble

Bubble#

class discopy.tensor.Bubble(name=None, dom=None, cod=None, data=None, *args, **kwargs)[source]#

Bases: discopy.monoidal.Bubble, Box

Bubble in a tensor diagram, applies a function elementwise.

Parameters:
  • inside (tensor.Diagram) – The diagram inside the bubble.

  • func (callable) – The function to apply, default is lambda x: int(not x).

Examples

>>> men = Box("men", Dim(1), Dim(2), [0, 1])
>>> mortal = Box("mortal", Dim(2), Dim(1), [1, 1])
>>> men_are_mortal = (men >> mortal.bubble()).bubble()
>>> assert men_are_mortal.eval(dtype=bool)
>>> men_are_mortal.draw(draw_type_labels=False,
...                     path='docs/_static/tensor/men-are-mortal.png')
../_images/men-are-mortal.png
>>> from sympy import Expr
>>> from sympy.abc import x
>>> f = Box('f', Dim(2), Dim(2), [1, 0, 0, x])
>>> g = Box('g', Dim(2), Dim(2), [-x, 0, 0, 1])
>>> def grad(diagram, var):
...     return diagram.bubble(
...         func=lambda x: getattr(x, "diff", lambda _: 0)(var),
...         drawing_name=f"d${var}$" )
>>> lhs = grad(f >> g, x)
>>> rhs = (grad(f, x) >> g) + (f >> grad(g, x))
>>> assert lhs.eval(dtype=Expr) == rhs.eval(dtype=Expr)
>>> from discopy.drawing import Equation
>>> Equation(lhs, rhs).draw(figsize=(5, 2), draw_type_labels=False,
...                         path='docs/_static/tensor/product-rule.png')
../_images/product-rule.png
grad(var, **params)[source]#

The gradient of a bubble is given by the chain rule.

>>> from sympy.abc import x
>>> g = Box('g', Dim(2), Dim(2), [2 * x, 0, 0, x + 1])
>>> f = lambda d: d.bubble(func=lambda x: x ** 2, drawing_name="f")
>>> lhs, rhs = Box.grad(f(g), x), f(g).grad(x)
>>> from discopy.drawing import Equation
>>> Equation(lhs, rhs).draw(draw_type_labels=False,
...                         path='docs/_static/tensor/chain-rule.png')
../_images/chain-rule.png