PEP 465 – Dedicated infix operators for matrix multiplication and matrix power
python.org
python.org
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.
I don't think you know what you're talking about.
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.
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)
This would make more sense to me.We could even have a reverse mnemonic: AlTernate Multiplication
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.
http://docs.python.org/2/reference/datamodel.html#emulating-...
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.
I wonder if a whole set of infix matrix operations could be added to reduce the need to load numpy for simple tasks.
A @* B
A @. B
A @+ B
[1] http://code.activestate.com/recipes/384122/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.
very loosely related, this reminds me of calling R functions from python that take keyword arguments with dots in their names.
>>> f(hello.world=123)
File "<stdin>", line 1
SyntaxError: keyword can't be an expression
so instead: >>> f(**{'hello.world':123})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 ?
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.
S = (H.dot(beta) - r).T.dot(inv(H.dot(V).dot(H.T))).dot(H.dot(beta) - r)
but this:
S = (( (H) .dot (beta) - (r) ).T) .dot (inv( (H) .dot (V) .dot ((H).T) )) .dot ( (H) .dot (beta) - (r) )
is close enough to:
S = (H @ beta - r).T @ inv(H @ V @ H.T) @ (H @ beta - r)
although bit less readable due to being bit longer.
http://code.activestate.com/recipes/384122-infix-operators/
The code there overrides | to construct arbitrary operators that are used by wrapping an object in |, like:
a |x| b
where x defines the custom behavior.