# [Numpy-discussion] How exactly ought 'dot' to work?

Nathaniel Smith njs at pobox.com
Sat Feb 22 17:37:40 EST 2014

```On Sat, Feb 22, 2014 at 5:17 PM, Matthew Brett <matthew.brett at gmail.com> wrote:
> The discussion might become confusing in the conflation of:
>
> * backward incompatible changes to dot
> * coherent behavior to propose in a PEP

Right, I definitely am asking about how we think the "ideal" dot
operator should work. The migration strategy to get to there from here
is a separate question, that will raise a bunch of details that are a
distraction from the fundamental question of what we *want*.

> If A @ B means 'matrix multiply A, B' - then it would be a shame to
> raise an error if A or B is a scalar.
>
> Sympy, for example, will allow matrix multiplication by a scalar,
> MATLAB / Octave too.

Interesting! We do disagree on this then. I feel strongly that given
separate matrix product and elementwise product operators @ and *,
then 'scalar @ matrix' should be an error, and if you want scalar
(elementwise) product then you should write 'scalar * matrix'.

Sympy, MATLAB, Octave are not really good guides, because either they
have only a single operator available (Sympy with *, np.matrix with
*), or they have an alternative operator available but it's annoying
to type and rarely used (MATLAB/Octave with .*).

For us, the two operators are both first-class, and we've all decided
that the scalar/elementwise operator is actually the more important
and commonly used one, and matrix multiply is the unusual case
(regardless of whether we end up spelling it 'dot' or '@'). So why
would we want a special case for scalars in dot/@? And anyway,
TOOWTDI.

Notation like 'L * X @ Y' really makes it immediately clear what sort
of operations we're dealing with, too.

> I have used > 2D dot calls in the past, maybe still do, I'm not sure.

Have you used dot(>2D, >2D)? That's the case that this proposal would
change -- dot(>2D, <=2D) is the same under both the outer product and

I feel pretty strongly that the broadcasting proposal is the right
thing, for consistency with other operators -- e.g., all ufuncs and
currently really the odd one out. The outer product functionality is
potentially useful, but it should be called np.dot.outer, because
logically it has the same relationship to np.dot that np.add.outer has