(x, y, axes=2)
return einsum(einsum_str, x, y)
Simple translation of tensordot syntax to einsum.
Simple translation of tensordot syntax to einsum.
Simple translation of tensordot syntax to einsum .
def tensordot(x, y, axes=2):
    """Simple translation of tensordot syntax to einsum."""
    torch, _ = _get_torch_and_device()

    if _TORCH_HAS_TENSORDOT:
        return torch.tensordot(x, y, dims=axes)

    xnd = x.ndimension()
    ynd = y.ndimension()

    # convert int argument to (list[int], list[int])
    if isinstance(axes, int):
        axes = range(xnd - axes, xnd), range(axes)

    # convert (int, int) to (list[int], list[int])
    if isinstance(axes[0], int):
        axes = (axes[0],), axes[1]
    if isinstance(axes[1], int):
        axes = axes[0], (axes[1],)

    # initialize empty indices
    x_ix = [None] * xnd
    y_ix = [None] * ynd
    out_ix = []

    # fill in repeated indices
    available_ix = iter(_torch_symbols_base)
    for ax1, ax2 in zip(*axes):
        repeat = next(available_ix)
        x_ix[ax1] = repeat
        y_ix[ax2] = repeat

    # fill in the rest, and maintain output order
    for i in range(xnd):
        if x_ix[i] is None:
            leave = next(available_ix)
            x_ix[i] = leave
            out_ix.append(leave)
    for i in range(ynd):
        if y_ix[i] is None:
            leave = next(available_ix)
            y_ix[i] = leave
            out_ix.append(leave)

    # form full string and contract!
    einsum_str = "{},{}->{}".format(*map("".join, (x_ix, y_ix, out_ix)))
    return einsum(einsum_str, x, y)
def tensordot ( x , y , axes = 2 ) : torch , _ = _get_torch_and_device ( ) if _TORCH_HAS_TENSORDOT : return torch . tensordot ( x , y , dims = axes ) xnd = x . ndimension ( ) ynd = y . ndimension ( ) # convert int argument to (list[int], list[int]) if isinstance ( axes , int ) : axes = range ( xnd - axes , xnd ) , range ( axes ) # convert (int, int) to (list[int], list[int]) if isinstance ( axes [ 0 ] , int ) : axes = ( axes [ 0 ] , ) , axes [ 1 ] if isinstance ( axes [ 1 ] , int ) : axes = axes [ 0 ] , ( axes [ 1 ] , ) # initialize empty indices x_ix = [ None ] * xnd y_ix = [ None ] * ynd out_ix = [ ] # fill in repeated indices available_ix = iter ( _torch_symbols_base ) for ax1 , ax2 in zip ( * axes ) : repeat = next ( available_ix ) x_ix [ ax1 ] = repeat y_ix [ ax2 ] = repeat # fill in the rest, and maintain output order for i in range ( xnd ) : if x_ix [ i ] is None : leave = next ( available_ix ) x_ix [ i ] = leave out_ix . append ( leave ) for i in range ( ynd ) : if y_ix [ i ] is None : leave = next ( available_ix ) y_ix [ i ] = leave out_ix . append ( leave ) # form full string and contract! einsum_str = "{},{}->{}" . format ( * map ( "" . join , ( x_ix , y_ix , out_ix ) ) ) return einsum ( einsum_str , x , y )