Einstein summation is used to simplify tensors, matrices, and vector expressions. It is a notational convention. In python, numpy provides a function named, einsum() that can compute the Einstein summation either implicitly or explicitly, as specified.

Numpy in the implicit mode, the einsum() function reduces multi-dimensional arrays in a simple way. When used explicitly, we can specify parameters to carry out summation over our desired arrays in non-stereotypical ways which are not the default Einstein summations.

This can be done by specifying the subscript parameter of the einsum() function. We will look at the syntax of the function in the following sections.

## 3 main properties of the Einstein Summation

There are three main properties of the Einstein summation that is used in advanced mathematics and physics for brevity. They are:

- Summation is carried over for indices that are repeated.
- The limit for the appearance of each index is two.
- Each term of the Einstein Summation can at most have two identical index.

## Syntax of the numpy.einsum() function

The einsum() function is written in the following manner:

numpy.einsum(subscripts, *operands, out, dtype, order, casting, optimize)

The parameters of the function are:

`subscripts: string type`

->specifies the list for comma separated subscripts when explicitly mentioned with the “->” sign. Otherwise, implicitly the classical Einstein Summation is calculated.`*operands: ndarray ->`

The arrays which are operated on.`out: ndarray-> (optional)`

If specified the Einstein summation is stored in this array.`dtype: data type-> (optional)`

If specified, forces the calculation to limit itself to a specified data type. The default value of this parameter is None.`order:{'C','F','A','K'}-> (optional)`

Determines the output’s memory structure . C= contiguous, F= Fortran contiguous, K=the same layout as the inputs and A= ‘F’ if inputs are all ‘F’ and ‘C’ otherwise.`casting{‘no’, ‘safe’, ‘unsafe’,‘equiv’,‘same_kind’}->optional`

Determines the type of casting that might occur with the data. ‘no’ means there should be no casting, ‘safe’ means the allowed values should be preserve, ‘unsafe’ ( not recommended) means all kinds of conversion is allowed, ‘equiv’ allows only byte-sized changes and ‘same_kind’ represents that only certain kind of casting such as float64 or float32 should be allowed. When not mentioned, the default is ‘safe’.`optimize{'optimal','greedy',True,False}->(optional)`

no optimization of intermediate resources occur if set to False, but when set to True, it will take up the default ‘greedy’ value.

The output of the function is:

Output: ndarray -> The Einstein Summation is returned.

## What else can einsum() do?

There are a lot of things that the einsum() function can perform. Let’s look at some of those functions:

- The einsum(‘ii’,”matrix_name”) function can find the trace of a matrix which can be determined by the numpy.trace(matrix) function .
- The equivalent of numpy.inner(matrix1, matrix2) can be calculated using einsum(‘i,i’,matrix1,matrix2) where i is the subscript.
- Matrix multiplications and dot products can be found out using einsum(‘ij,jk’, matrix1, matrix2).
- Other functions such as transposes, diagonals and permutations can also be performed using the einsum() function.
- einsum_path() can also calculate chained matrix operations.

## Implementing the Einsum() summation function

Before we jump head first into the code, we have to make sure we have the required modules in our system. Run the following code in your command prompt in administrator mode before importing numpy.

```
pip install numpy
```

Now, let’s take a one dimensional array from the user in the form of a list and then calculate the Einstein summation.

```
#importing required modules
import numpy as np
#determining length of array
N,j=int(input("Enter size of arrays= ")),0
#for two matrices at a time
while(j<2):
arrayy=[]
for i in range(N):
#taking user input of individual elements
ele=int(input("Enter "+str(i+1)+"th element of the "+str(j+1)+"th array = "))
arrayy.append(ele)
if(j==0):
#creating the first matrix
arr1=np.array(arrayy)
else:
#creating the second matrix
arr2=np.array(arrayy)
j+=1
# Original arrays after taking user input
print("The first array or matrix is =",arr1)
print("The second array or matrix is =",arr2)
#calculating the einstein summation
result = np.einsum("n,n", arr1, arr2)
#displaying the einstein summation of the given arrays
print("The Einstein Summation is =", result)
```

**The output would be:**

```
Enter size of arrays= 2
Enter 1th element of the 1th array = 45
Enter 2th element of the 1th array = 50
Enter 1th element of the 2th array = 75
Enter 2th element of the 2th array = 80
The first array or matrix is = [45 50]
The second array or matrix is = [75 80]
The Einstein Summation is = 7375
```

*Suggested: Flattening nested lists in Python*

## Using numpy.arange() along with einsum()

In the next example, lets create a numpy array using arange() and reshape() functions and then compute the Einstein summation of the two arrays.

```
#importing required modules
import numpy as np
#creating the numpy arrays
arr1=np.arange(18,36,2).reshape(3,3)
arr2=np.arange(38,56,2).reshape(3,3)
#displaying the original arrays
print("The first array or matrix is =",arr1)
print("The second array or matrix is =",arr2)
#calculating the einstein summation
result = np.einsum("ij,jk", arr1, arr2)
#displaying the einstein summation of the given arrays
print("The Einstein Summation is =", result)
```

The output will be:

```
The first array or matrix is = [[18 20 22]
[24 26 28]
[30 32 34]]
The second array or matrix is = [[38 40 42]
[44 46 48]
[50 52 54]]
The Einstein Summation is = [[2664 2784 2904]
[3456 3612 3768]
[4248 4440 4632]]
```

*Do check out: How To Find Nearest Value In Numpy Array?*

## Summary

In this tutorial, we have looked at how we can use the numpy.einsum() function for computing the Einstein Summation of two array like matrices. We have gone through the syntax of the einsum() function and looked at how it can be used for various computations such as determining the transpose, the dot products of matrices as well.

Through the two examples mentioned here, we have tried to implement the function on a one dimensional and a two-dimensional array. To know more about the einsum() function, visit the official documentation.