Python ValueError: non-broadcastable output operand with shape () doesn't match the broadcast shape (50,)

2.3k views Asked by At

I'm using numpy to compute the cross product of two arrays, but I'm running into the following error:

ValueError: non-broadcastable output operand with shape () doesn't match the broadcast shape (50,)

I have three variables which are of type numpy.ndarray and represent row vectors:

  • n = [0 0 1]
  • beta = [array with 50 elements, 0, array with 50 elements]
  • betap = [array with 50 elements, 0, array with 50 elements]

The first and third elements of beta represent the result of the following piecewise functions:

t_start = (-2 * 0.01) / 299792458
t_end = (3 * 0.01) / 299792458
t = np.linspace(t_start, t_end)

x_of_t = = np.piecewise(t,
                      [np.logical_or(t < t_start, t > t_end), np.logical_and(t_start <= t, t <= t_end)],
                      [((0.01 * 0.02) / (2 * np.pi * 2)), (lambda t: (0.01 * 0.02) / (2 * np.pi * 2) * np.cos((2 * np.pi)/0.01 * 299792458 * t))])

z_of_t = np.piecewise(t, 
                      [t < t_start, t > t_end, np.logical_and(t_start <= t, t <= t_end)], 
                      [(lambda t: (np.sqrt(0.75) * 299792458 * (t - t_start) + np.sqrt(0.75) * (1 - 0.02**2 / (4 * np.sqrt(0.75) * 2**2)) * 299792458 * t_start - 0.01 * 0.02**2 / (16 * np.pi * np.sqrt(0.75) * 2**2) * np.cos(2 * ((2 * np.pi)/0.01) * 299792458 * t_start))), 
                       (lambda t: np.sqrt(0.75) * 299792458 * (t - t_end) + np.sqrt(0.75) * (1 - 0.02**2 / (4 * np.sqrt(0.75) * 2 **2)) * 299792458 * t_end - 0.01 * 0.02**2 / (16 * np.pi * np.sqrt(0.75) * 2 **2) * np.cos(2 * ((2 * np.pi)/0.01) * 299792458 * t_end)),
                       (lambda t: np.sqrt(0.75) * (1 - 0.02**2 / (4 * np.sqrt(0.75) * 2 **2)) * 299792458 * t - 0.01 * 0.02**2 / (16 * np.pi * np.sqrt(0.75) * 2**2) * np.cos(2 * ((2 * np.pi)/lambda_u) * 299792458 * t))])

The first and third elements of betap represent the derivatives of these functions. I am calculating the derivatives using numpy's gradient function np.gradient(beta_x_of_t) so the array lengths will match (len = 50). Similarly, when checking the shape of n, beta, and betap, they all have the same shape (3,). Checking the shape of the first and third elements of beta and betap gives the following shape: (50,).

Given that the shapes are the same, I thought I should be able to perform the cross-product using np.cross(n-beta, betap), but I get the above error.

My goal here is twofold:

  1. Understand what the error message means. For example, I've looked over many other questions posted here, but I haven't seem someone answer what it means for an output operand to be non-broadcastable.
  2. Using that information, solve the error to compute the cross product.
1

There are 1 answers

4
hpaulj On

From the np.cross docs, 2 sample arrays:

In [51]: x = np.array([[1,2,3], [4,5,6]])
    ...: y = np.array([[4,5,6], [1,2,3]])
    ...: 
In [52]: np.cross(x[0],y[0])
Out[52]: array([-3,  6, -3])
In [53]: np.cross(x,y)
Out[53]: 
array([[-3,  6, -3],
       [ 3, -6,  3]])

Thus, cross is taking 2 vector cross products. So it can take (n,3) arrays, and return a (n,3) result. (or (n,2) for a 2d vector cross).

And of course a cross with itself is 0

In [59]: np.cross(x,x)
Out[59]: 
array([[0, 0, 0],
       [0, 0, 0]])

Lets make a list like your beta:

In [60]: beta = [np.arange(3),0,np.arange(3)]
In [61]: beta
Out[61]: [array([0, 1, 2]), 0, array([0, 1, 2])]

numpy doesn't like to make an array from such a list:

In [62]: np.array(beta)
<ipython-input-62-f4485c3a6e4c>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  np.array(beta)
Out[62]: array([array([0, 1, 2]), 0, array([0, 1, 2])], dtype=object)

But let's try to perform cross on such a (3,) shaped array:

In [64]: barr = np.array(beta,object)
In [65]: barr
Out[65]: array([array([0, 1, 2]), 0, array([0, 1, 2])], dtype=object)
In [66]: np.cross(barr, barr)
Traceback (most recent call last):
  File "<ipython-input-66-7218b4a081e0>", line 1, in <module>
    np.cross(barr, barr)
  File "<__array_function__ internals>", line 5, in cross
  File "/usr/local/lib/python3.8/dist-packages/numpy/core/numeric.py", line 1655, in cross
    cp0 -= tmp
ValueError: non-broadcastable output operand with shape () doesn't match the broadcast shape (3,)

That looks like your error.

np.cross is intended for use with (N,3) shaped numeric dtype arrays. An object dtype array like your beta is wrong. I'm not even sure what you intend to be happening.

Most of your question is extraneous, that has nothing to do with the error. Your question should have shown the traceback, and clearly stated the shape and dtype of the arguments.