module testing.einsum.einsum_impl_ext#

Short summary#

module mlprodict.testing.einsum.einsum_impl_ext

Functions implemented einsum computation for two matrices having the same dimensions.

source on GitHub

Functions#

function

truncated documentation

_common_check_numpy_extended_dot

Common verifications for all implementations of numpy_extended_dot().

_numpy_extended_dot_equation

Returns the equation equivalent to an extended version of an aligned matrix multiplication (see numpy_extended_dot()). …

_numpy_extended_dot_python_intermediate

_numpy_extended_dot_python_l1l2l3

_numpy_extended_dot_python_update_broadcast

numpy_diagonal

Extracts diagonal coefficients from an array.

numpy_extended_dot

Extended version of a matrix multiplication (numpy.dot) with two matrices m1, m2 of the same dimensions. …

numpy_extended_dot_matrix

Implementation of numpy_extended_dot() using dot product, multiplication, transpose and reduction but not …

numpy_extended_dot_ouput_shape

Computes the output shape of results produced by function numpy_extended_dot

numpy_extended_dot_python

Implementation of numpy_extended_dot() in pure python. This implementation is not efficient but shows how to …

Documentation#

Functions implemented einsum computation for two matrices having the same dimensions.

source on GitHub

mlprodict.testing.einsum.einsum_impl_ext._common_check_numpy_extended_dot(m1, m2, axes, left, right)#

Common verifications for all implementations of numpy_extended_dot.

source on GitHub

mlprodict.testing.einsum.einsum_impl_ext._numpy_extended_dot_equation(m1_dim, m2_dim, axes, left, right)#

Returns the equation equivalent to an extended version of an aligned matrix multiplication (see numpy_extended_dot).

Parameters:
  • m1 – number of dimensions of the first matrix

  • m2 – number of dimensions of the second matrix

  • axes – summation axes

  • axes – summation axes

  • left – left axes

  • right – right axes

Returns:

equation

<<<

import numpy
from mlprodict.testing.einsum.einsum_impl_ext import (
    numpy_extended_dot_python, _numpy_extended_dot_equation)

a = numpy.arange(6).reshape((3, 2, 1))
b = numpy.arange(12).reshape((3, 1, 4))

print(numpy_extended_dot_python(
    a, b, axes=(0, ), left=(1,), right=(2,)))

# Equivalent einsum equation
print('equation', _numpy_extended_dot_equation(
    len(a.shape), len(a.shape), axes=(0, ), left=(1,), right=(2,)))

# Same einsum computation written in a different way.
print(numpy.einsum('kix,kxj->xij', a, b))

>>>

    [[[40 46 52 58]
      [52 61 70 79]]]
    equation aBc,abC->BC
    [[[40 46 52 58]
      [52 61 70 79]]]

source on GitHub

mlprodict.testing.einsum.einsum_impl_ext._numpy_extended_dot_python_intermediate(m1_shape, m2_shape, l1, l2, l3)#
mlprodict.testing.einsum.einsum_impl_ext._numpy_extended_dot_python_l1l2l3(m1_dim, axes, left, right)#
mlprodict.testing.einsum.einsum_impl_ext._numpy_extended_dot_python_update_broadcast(m1, m2, axes, left, right, l1, l2, l3, names, broadcast, cols, kind, common, verbose=False)#
mlprodict.testing.einsum.einsum_impl_ext.numpy_diagonal(m, axis, axes)#

Extracts diagonal coefficients from an array.

Parameters:
  • m – input array

  • axis – kept axis among the diagonal ones

  • axes – diagonal axes (axis must be one of them)

Returns:

output

<<<

import numpy
from mlprodict.testing.einsum import numpy_diagonal

mat = numpy.arange(8).reshape((2, 2, 2))
print(mat)
diag = numpy_diagonal(mat, 1, [1, 2])
print(diag)

>>>

    [[[0 1]
      [2 3]]
    
     [[4 5]
      [6 7]]]
    [[0 3]
     [4 7]]

source on GitHub

mlprodict.testing.einsum.einsum_impl_ext.numpy_extended_dot(m1, m2, axes, left, right, verbose=False)#

Extended version of a matrix multiplication (numpy.dot) with two matrices m1, m2 of the same dimensions. Loops over left axes for m1 and right axes for m2, summation is done over axes. Other axes must be empty. This multiplication combines matrix multiplication (dot) and broadcasted multiplication term by term.

Parameters:
  • m1 – first matrix

  • m2 – second matrix

  • axes – summation axes

  • left – left axes

  • right – right axes

  • verbose – display intermediate information

Returns:

output

The dot product is equivalent to:

<<<

import numpy
from mlprodict.testing.einsum import numpy_extended_dot

m1 = numpy.arange(4).reshape((2, 2))
m2 = m1 + 10
print("dot product")
print(m1 @ m2)

dm1 = m1.reshape((2, 2, 1))
dm2 = m2.reshape((1, 2, 2))
dot = numpy_extended_dot(dm1, dm2, axes=[1], left=[0], right=[2],
                         verbose=True)
print("extended dot product")
print(dot)

>>>

    dot product
    [[12 13]
     [56 61]]
      [numpy_extended_dot] Abc,abC->AC: (2, 2, 1) @ (1, 2, 2)
      [numpy_extended_dot] (2, 2) reshaped into [2, 1, 2] 
    extended dot product
    [[[12 13]]
    
     [[56 61]]]

Empty axes should be squeezed to get identical results. Dot product when the second matrix is transposed.

<<<

import numpy
from mlprodict.testing.einsum import numpy_extended_dot

m1 = numpy.arange(4).reshape((2, 2))
m2 = m1 + 10
print("dot product")
print(m1 @ m2.T)

dm1 = m1.reshape((2, 1, 2))
dm2 = m2.reshape((1, 2, 2))
dot = numpy_extended_dot(dm1, dm2, axes=[2], left=[0], right=[1],
                         verbose=True)
print("extended dot product")
print(dot)

>>>

    dot product
    [[11 13]
     [53 63]]
      [numpy_extended_dot] Abc,aBc->AB: (2, 1, 2) @ (1, 2, 2)
      [numpy_extended_dot] (2, 2) reshaped into [2, 2, 1] 
    extended dot product
    [[[11]
      [13]]
    
     [[53]
      [63]]]

An example when right axes include the summation axis.

<<<

import numpy
from mlprodict.testing.einsum import numpy_extended_dot

m1 = numpy.arange(4).reshape((2, 2))
m2 = m1 + 10
dm1 = m1.reshape((2, 2, 1))
dm2 = m2.reshape((1, 2, 2))
dot = numpy_extended_dot(dm1, dm2, axes=[2], left=[0], right=[1, 2],
                         verbose=True)
print(dot)

>>>

      [numpy_extended_dot] Abc,aBc->ABc: (2, 2, 1) @ (1, 2, 2)
      [numpy_extended_dot] (2, 2, 2) reshaped into [2, 2, 2] 
    [[[10 11]
      [12 13]]
    
     [[50 55]
      [60 65]]]

Example in higher dimension:

<<<

import numpy
from mlprodict.testing.einsum import numpy_extended_dot

m1 = numpy.arange(8).reshape((2, 2, 2))
m2 = m1 + 10

dot = numpy_extended_dot(m1, m2, [1], [0], [2], verbose=True)
print(dot)

>>>

      [numpy_extended_dot] Abc,abC->AC: (2, 2, 2) @ (2, 2, 2)
      [numpy_extended_dot] (2, 2) reshaped into [2, 1, 2] 
    [[[164 176]]
    
     [[580 624]]]

The current implementation still uses numpy.einsum but this should be replaced.

source on GitHub

mlprodict.testing.einsum.einsum_impl_ext.numpy_extended_dot_matrix(m1, m2, axes, left, right, verbose=False)#

Implementation of numpy_extended_dot using dot product, multiplication, transpose and reduction but not a custom python implementation like numpy_extended_dot_python.

<<<

import numpy
from mlprodict.testing.einsum import numpy_extended_dot_matrix
from mlprodict.testing.einsum.einsum_impl_ext import (
    _numpy_extended_dot_equation)

a = numpy.arange(6).reshape((3, 2, 1))
b = numpy.arange(12).reshape((3, 1, 4))

print(numpy_extended_dot_matrix(
    a, b, axes=(0, ), left=(1,), right=(2,)))

# Equivalent einsum equation
print('equation', _numpy_extended_dot_equation(
    len(a.shape), len(a.shape), axes=(0, ), left=(1,), right=(2,)))

# Same einsum computation written in a different way.
print(numpy.einsum('kix,kxj->xij', a, b))

>>>

    [[[40 46 52 58]
      [52 61 70 79]]]
    equation aBc,abC->BC
    [[[40 46 52 58]
      [52 61 70 79]]]

source on GitHub

mlprodict.testing.einsum.einsum_impl_ext.numpy_extended_dot_ouput_shape(m1, m2, axes, left, right)#

Computes the output shape of results produced by function numpy_extended_dot or numpy_extended_dot_python.

source on GitHub

mlprodict.testing.einsum.einsum_impl_ext.numpy_extended_dot_python(m1, m2, axes, left, right, verbose=False)#

Implementation of numpy_extended_dot in pure python. This implementation is not efficient but shows how to implement this operation without numpy.einsum.

<<<

import numpy
from mlprodict.testing.einsum import numpy_extended_dot_python
from mlprodict.testing.einsum.einsum_impl_ext import (
    _numpy_extended_dot_equation)

a = numpy.arange(6).reshape((3, 2, 1))
b = numpy.arange(12).reshape((3, 1, 4))

print(numpy_extended_dot_python(
    a, b, axes=(0, ), left=(1,), right=(2,)))

# Equivalent einsum equation
print('equation', _numpy_extended_dot_equation(
    len(a.shape), len(a.shape), axes=(0, ), left=(1,), right=(2,)))

# Same einsum computation written in a different way.
print(numpy.einsum('kix,kxj->xij', a, b))

>>>

    [[[40 46 52 58]
      [52 61 70 79]]]
    equation aBc,abC->BC
    [[[40 46 52 58]
      [52 61 70 79]]]

source on GitHub