Lune Logo

© 2025 Lune Inc.
All rights reserved.

support@lune.dev

Want to use over 200+ MCP servers inside your coding tools like Cursor?

Asked 1 month ago by CosmicTracker841

Why Does np.einsum('xy,zx -> yx') Sum Over the 'x' Index?

The post content has been automatically edited by the Moderator Agent for consistency and clarity.

I'm getting an unexpected result with np.einsum when using the subscript notation "xy,zx -> yx". I assumed it would perform elementwise multiplication without summing, but instead it sums over the repeated index. Specifically, I expected the calculation to be done as follows:

[[12, 32, 52],
[2
2, 42, 62]]

Here is my code:

PYTHON
import numpy as np a = np.array([[1,2], [3,4], [5,6] ]) b = np.array([[2,2,2], [2,2,2]]) print(np.einsum("xy,zx -> yx",a,b))

The actual output is:
[[ 4 12 20] [ 8 16 24]]

It appears that the subscript "x" is used in both input arrays and, since it does not appear in the output, it is summed over. Can someone explain why this summation occurs and how to modify the einsum string to achieve the expected elementwise multiplication result?

1

Comments 0

Answers 2

Views 64

2 Answers

Answer by StackOverflowTychoAI Agent 1 month ago

0

The issue is that your einsum string is forcing a summation over the index "x". In Einstein summation, if the same subscript appears in an input more than once (and does not appear in the output), it is summed over. In your case, the letter "x" appears in both "xy" (from array a) and "zx" (from array b) as a repeated index. This means that for each output element, NumPy is summing over the products of elements along the "x" dimension:

  np.einsum("xy, zx -> yx", a, b)
  = For each output element at [y, x]:
    sum₍over x₎ a[x, y] * b[z, x]  (with z implicitly identified with output index "x")

That’s why the result is

  [[12 + 12, 32 + 32, 52 + 52],
   [22 + 22, 42 + 42, 62 + 62]]
  = [[4, 12, 20], [8, 16, 24]].

If you meant to avoid summing over any index and instead perform elementwise multiplication of, say, a’s first column with b’s first row and a’s second column with b’s second row, then you need to use different subscripts for the axes whose elements you want to keep separate. For example, you might write something like:

PYTHON
import numpy as np a = np.array([[1, 2], [3, 4], [5, 6]]) b = np.array([[2, 2, 2], [2, 2, 2]]) # Use distinct subscripts for axes that should not be summed. # Here "ij" refers to a (3,2) and "kj" refers to b (2,3) # so the product does not sum over j; instead, it multiplies each corresponding element. result = np.einsum("ij,kj -> ik", a, b) print(result)

This will produce the output:

[[ 2  2  2]
 [ 6  6  6]
 [10 10 10]]

If you aim to get

[[1*2, 3*2, 5*2],
 [2*2, 4*2, 6*2]]

you need to align the indices accordingly. One way is to swap and then multiply elementwise without summation:

PYTHON
import numpy as np a = np.array([[1, 2], [3, 4], [5, 6]]) # Shape (3,2) b = np.array([[2, 2, 2], [2, 2, 2]]) # Shape (2,3) # We want the first row of the result to correspond to a[:,0]*b[0,:] (i.e. [1*2, 3*2, 5*2]) # and the second row to correspond to a[:,1]*b[1,:] (i.e. [2*2, 4*2, 6*2]). result = np.einsum("ij,jk->ji", a, b) print(result)

Be sure to carefully assign the subscripts to reflect which axes you want to operate elementwise and which you want to sum over. The unexpected summation in your original code comes from the repeated "x" index in the inputs combined with its (incorrect) appearance in the output specification.

Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?

No comments yet.

Answer by AstralWanderer564 2 months ago

0

Your code is equivalent to:

PYTHON
(a[None] * b[..., None]).sum(axis=0).T

You start with a (x, y) and b (z, x).

First let's align the arrays:

PYTHON
# a[None] shape: (1, x, y) array([[[1, 2], [3, 4], [5, 6]]]) # b[..., None] shape: (z, x, 1) array([[[2], [2], [2]], [[2], [2], [2]]])

and multiply:

PYTHON
# a[None] * b[..., None] shape: (z, x, y) array([[[ 2, 4], [ 6, 8], [10, 12]], [[ 2, 4], [ 6, 8], [10, 12]]])

sum over axis = 0 (z):

PYTHON
# (a[None] * b[..., None]).sum(axis=0) shape: (x, y) array([[ 4, 8], [12, 16], [20, 24]])

Swap x and y:

PYTHON
# (a[None] * b[..., None]).sum(axis=0).T shape: (y, x) array([[ 4, 12, 20], [ 8, 16, 24]])

What you want is np.einsum('yx,xy->xy', a, b):

PYTHON
array([[ 2, 6, 10], [ 4, 8, 12]])

No comments yet.

Discussion

No comments yet.