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.
Functions#
function |
truncated documentation |
---|---|
Common verifications for all implementations of |
|
Returns the equation equivalent to an extended version of an aligned matrix multiplication (see |
|
Extracts diagonal coefficients from an array. |
|
Extended version of a matrix multiplication (numpy.dot) with two matrices m1, m2 of the same dimensions. … |
|
Implementation of |
|
Computes the output shape of results produced by function |
|
Implementation of |
Documentation#
Functions implemented einsum computation for two matrices having the same dimensions.
- 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
.
- 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]]]
- 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]]
- 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.
- 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 likenumpy_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]]]
- 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
ornumpy_extended_dot_python
.
- 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]]]