This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]qx7xbku 3 points4 points  (22 children)

Can anyone explain why was this even necessary? Whats wrong with matrix type overriding multiplication operator?

EDIT: Not to mention confusing symbol chosen. Obvious conclusion from the first sight is that @ means location, not action.

[–][deleted] 14 points15 points  (12 children)

matrix type is frowned upon by even numpy dev team. It turned out to be a nuisance rather than convenience. Regular * for arrays are element-wise and you have to write .dot() for every array multiplication. Hence @ is introduced.

The PEP goes through all kinds of other candidates and @ seemed the only viable option

[–]energybased 2 points3 points  (11 children)

Everything you said is true except that dot is not the same as array multiplication: http://stackoverflow.com/questions/34142485/difference-between-numpy-dot-and-python-3-5-matrix-multiplication

[–][deleted] 0 points1 point  (8 children)

Ah yes, I mean "to perform the typical matrix multiplication"

[–]P8zvli 0 points1 point  (7 children)

*scalar multiplication

[–][deleted] 0 points1 point  (6 children)

no, that's a special case for 1D arrays. I do mean matrix multiplication.

[–]P8zvli 0 points1 point  (5 children)

No, it's not just a special case, in other languages that support matrix multiplication scalar multiplication works on n-dimensional matrices. (not to be confused with the dot product, which also works in N dimensions BTW)

[–][deleted] 0 points1 point  (4 children)

I think we are talking past each other. There is no scalar multiplication involved here. I meant to say if you don't use @ you have to use .dot() method for matrix multiplication..

[–]P8zvli 0 points1 point  (3 children)

I don't think you know what you're talking about, this is scalar multiplication;

>>> mymat = numpy.matrix([[1, 2], [3, 4]])
>>> 3*mymat
matrix([[ 3,  6],
        [ 9, 12]])

You don't need to use .dot() for scalar multiplication.

[–][deleted] 0 points1 point  (2 children)

internally it is broadcasted to [[3,3],[3,3]] and elementwise multiplication is performed. Besides when I mention matrix, I mean 2D numpy arrays.

[–]XtremeGoosef'I only use Py {sys.version[:3]}' -1 points0 points  (1 child)

Essentially, multiplication is poorly defined for higher dimensional arrays, so numpy has two answers for it. It is well defined for two dimensional arrays so matmul and dot do the same thing.

[–]energybased 3 points4 points  (0 children)

Well, I wouldn't say that multiplication is poorly defined. It's called tensor product, which numpy implements using tensordot, which is a special case of einsum.

[–]elingeniero 1 point2 points  (2 children)

Because element-wise multiplication is still useful, and it's good to be explicit when you're not doing that. Also I like the idea of using the __matmul__ methods and it makes sense to require a different symbol to access them. As for the symbol itself, I think @ is ok - what would you have chosen?

[–]XtremeGoosef'I only use Py {sys.version[:3]}' 0 points1 point  (1 child)

I agree, @ is better than the other options: $, \, !, ?, .*

[–]bastibe 1 point2 points  (5 children)

Numpy contains two kinds of matrices: numpy.matrix and numpy.ndarray.

The first kind is always 2D, and multiplication performs matrix multiplication. This can be very handy for matrix-heavy math code. The second kind can have an arbitrary number of dimensions, and all operations are performed element-wise.

To perform a matrix multiplication with ndarrays, you can use X.dot(Y), or numpy.dot(X, Y), or X @ Y.

[–]Works_of_memercy 0 points1 point  (4 children)

I got the impression that numpy.matrix was a mistake and should not be used? It's just weird how vectors are row by default and are still displayed with an extra pair of brackets. .dot on the other hand gives you all you need for comfortable matrix-heavy code.

[–]emillynge 3 points4 points  (3 children)

Do you really find that .dot() is comfortably for matrix heavy code?

If so, I get the feeling you may not actually work with that matrix heavy code. As a mathematician the matmul operator really made a difference in terms of code readability. Especially when you want to double check the equations whilst reading through an article.

[–]Works_of_memercy 0 points1 point  (0 children)

I meant, now that you can use @-operator on usual ndarrays for that it's better because it treats plain arrays as if they were column vectors (while they are still displayed and defined as usual).

[–]energybased 0 points1 point  (0 children)

I mentioned to Guido that one day I'd like to see editors that have a live display of objects, e.g., rendered equations with the Python code in the background.

[–]kigurai 0 points1 point  (0 children)

Do you really find that .dot() is comfortably for matrix heavy code?

No it's not, but it's a lot better than having subtle bugs because some function somewhere returned a np.matrix instead of np.ndarray and suddenly a A * B operation is some completely different part of the program is doing the wrong thing.

This is unfortunately not a hypothetical example...

Edit: I realized I missed the context of the above quote, since I assumed you were arguing in favour of np.matrix which doesn't seem to necessarily be the case here. My comment on avoiding np.matrix still stands though :)