I'm still bothered by what Nathaniel mentioned about mixing 1d and 2d arrays

c = np.arange(4) a = np.arange(16).reshape(4,4) cc = c[:,None]

a.dot(c).dot(c.T) 420

a.dot(c.dot(c.T)) array([[ 0, 14, 28, 42], [ 56, 70, 84, 98], [112, 126, 140, 154], [168, 182, 196, 210]])

a.dot(cc).dot(cc.T) array([[ 0, 14, 28, 42], [ 0, 38, 76, 114], [ 0, 62, 124, 186], [ 0, 86, 172, 258]])

a.dot(cc.dot(cc.T)) array([[ 0, 14, 28, 42], [ 0, 38, 76, 114], [ 0, 62, 124, 186], [ 0, 86, 172, 258]])

hint:

c.dot(c.T) 14

and I expect it will be a lot more fun if we mix in some 3d or nd arrays. I think some of the decisions should not be driven by what is the most convenient for the usual cases, but by how easy it is to read your code and find the bugs where we made "silly" mistakes. A biased view from someone who learned how to use numpy and scipy by debugging. Matlab and GAUSS are user friendly, they don't allow for reduced dimension and never steal an axis in a reduce operation. I didn't manage to come up with more difficult examples (and ran out of time)

(a.dot(c).dot(c.T)).dot(2*a) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'numpy.int32' object has no attribute 'dot'

If we make too many mistakes, then numpy tells us. In the above examples, the scalar dot matrix would raise according to the PEP. I cannot come up with examples where we mix 3d and 2d and 1d because dot currently doesn't do it. "sane-left" Josef