Huh? Isn't it a question of whether you are doing matrix or array ops, so the type system is the issue? I have rarely needed to do elementwide multiply on matrices, and if I do, in Eigenproblem I can just call mat.array() to get an ArrayView.
Really, the problem is that NumPy is a crappily designed library primarily intended for array ops, and is just not well suited for linear algebra.
Use a second type that defines __mul__ as matrix multiplication:
As discussed above (Background: What's wrong with the status quo?), this has been tried this for many years via the numpy.matrix type (and its predecessors in Numeric and numarray). The result is a strong consensus among both numpy developers and developers of downstream packages that numpy.matrix should essentially never be used, because of the problems caused by having conflicting duck types for arrays. (Of course one could then argue we should only define __mul__ to be matrix multiplication, but then we'd have the same problem with elementwise multiplication.) There have been several pushes to remove numpy.matrix entirely; the only counter-arguments have come from educators who find that its problems are outweighed by the need to provide a simple and clear mapping between mathematical notation and code for novices (see Transparent syntax is especially crucial for non-expert programmers). But, of course, starting out newbies with a dispreferred syntax and then expecting them to transition later causes its own problems. The two-type solution is worse than the disease.
Of course it's an array library. The fact that it's not designed for your problem doesn't mean it's designed crappily.
Suppose you ported Eigen to Python. You'd still need an array library, so you could represent the inputs and outputs in a way that's usable in Python. You'd probably use NumPy.
So it appears that we will indeed have @ for matrix multiplication in Python 3.5! This is a feature the numeric python computing has been hoping for for a long, long time.
It kind of seems to me that it's actually vectored multiplication that's the odd one out that should maybe have a special syntax, maybe even one that applies to many operations and not just multiplication.
A matrix is a Thing that happens to also be a collection. A vector you want to multiply is just a collection. Really vector multiplication is just a map operation, so make some syntactic sugar to generate an operator comprehension:
a = [1,2,3]
b = [4,5,6]
c = a [*] b # or something
# becomes
c = [x * y for (x,y) in zip(a,b)]
# or
c = a.__vecmul__(b)
Great! Minor quibble: the underlying method names should not mention `mat` (e.g. `__matmul__`); instead mentioning the shape of the operator (e.g. `__atmul__`).
many existing python infix boolean operators resolve to method names based on the meaning, rather than the symbol. e.g. `a + b` resolves to `a.__add__(b)` rather than `a.__plus__(b)`, `x * * y` resolves to `x.__pow__(y)` rather than `x.__asteriskasterisk__(y)`, say. so arguably it would be consistent to name @ after the common meaning also.
on the other hand, "consistency is not necessarily a virtue: one can be consistently obnoxious" - C.A.B. Smith
that said, i like the idea that @ should be more general than just for matrices. an arbitrary infix boolean operation, neither necessarily commutative nor invertible.
even when talking about matrix multiplication, generalising slightly from arrays to abstract elements of vector spaces, and from matrices to linear transformations between vector spaces leaves you writing the same kinds of expressions that compose linear transformations without anything necessarily being represented as a matrix.
This. It allows for the general meaning to be conveyed (it's numeric, kind of multiplicative, uses @ symbol) without restricting it to a particular use case.
This allows other users to define their own meanings for @ in a variety of contexts.
We could even have a reverse mnemonic: AlTernate Multiplication
Julia also adopted this syntax, and I'm not sure if I like it. In numpy at least, I find myself doing element-wise multiplication much more frequently than matrix multiplication, so '.*' always feels clumsy. I'd rather have special syntax for the matrix multiply (and I was a long time matlab user before moving to numpy).
I have not witnessed this behavior, but it would be perfectly logical to dismiss R while absorbing its features – R is a domain-specific language (statistics) while Python is a general purpose programming language. A GP language will always have a larger useful scope than a DSL.
Sure, the facilities for statistics and plotting are well exposed. But all the features you need for 'general purpose' are in there too, and they aren't awkward to access (at least, relative to anything else).
Yes, but making it part of the language would bring clear error messages in case of misuse, and would allow the use of a different token, e.g. ":", as in smalltalk
The bloody associativity issue is unresolved...? Of course it should be right associative.
Otherwise ABx means (AB)x which is idiotic for numerical work. One would have to write A(Bx) to get reasonable performance which isn't far enough away from A.dot(B.dot(x)) to justify the implementation overhead.
Lastly, as awful as it sounds, it is nice when awfully expensive things like 10K by 10K matmats have some visual weight. It makes people think about how they're written down.
I'm kind of baffled by this. Python has operator overloading, so what's wrong with using * for matrix multiplication? I know there's a bit in the PEP that claims to answer this, but I can't understand their argument. Can someone explain?
It looks like it says there are enough cases where libraries crave two multiplication operators, elementwise multiplication and matrix multiplication, that it makes sense to add an operator to the language.
Would matrix multiplicqtion be useful for anything other than matrices ? I can understand to provide an operator in the language when it's usable by many types, but i don't understand what sense would it have to create an operator just for one type... Even more so when that type isn't part of the language.
Or does it mean that @ would be used just for arrays, and that it would be useful for cases when arrays aren't matrices of numbers ?
It does away with the need for a separate matrix type.
When you are using numpy (most imported non stdlib library according to the pep!) and you have two arrays a and b, a * b is elementwise multiplication.
numpy currently has a matrix type. When a and b are both matrices, a * b is matrix multiplication.
The @ operator would do away with the need for a matrix type. Then, a * b is element wise and a @ b is matrix wise, and a and b are always the same type. This would simplify numpy and lots of things that are based on it.
"The @ operator would do away for a matrix type" which is only an issue because every lib needs to define its own matrix type ? Then why isn't the solution to provide this type in the standard lib ?
I'd really like to see user-defined infix operators such as those in Haskell. There are some baked into the standard library (*+-/ etc), but you can also roll your own, so people could make do until this gets accepted.
Why not overload the already-defined * * ? Matrix multiplication is used much more than matrix exponentation (which can be delegated to methods), and * * is already right associative.
Because already means element-wise power. The reason we need a new operator (@) for matrix multiplication is precisely so we can all the same operators for arrays that we already use for scalars.
Really, the problem is that NumPy is a crappily designed library primarily intended for array ops, and is just not well suited for linear algebra.