[Python-ideas] [RFC] draft PEP: Dedicated infix operators for matrix multiplication and matrix power
Nathaniel Smith
njs at pobox.com
Fri Mar 14 17:41:36 CET 2014
More information about the Python-ideas mailing list
Fri Mar 14 17:41:36 CET 2014
- Previous message: [Python-ideas] [RFC] draft PEP: Dedicated infix operators for matrix multiplication and matrix power
- Next message: [Python-ideas] [RFC] draft PEP: Dedicated infix operators for matrix multiplication and matrix power
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Fri, Mar 14, 2014 at 2:53 PM, Paul Moore <p.f.moore at gmail.com> wrote: > One genuine question though - when the PEP was developed, were > multi-character operators like .* or <*> considered? A "rejected > alternative operator symbols" would be a useful addition to the PEP > (although it'd rob all us non-experts of the opportunity to bikeshed > :-)) > > On a related note, the @@ operator is visually dreadful (far too > heavy). While I see the */** analogy, and I appreciate that there's > few good options, I'd definitely like to see some evidence that it's > "the best of a bad lot" in the PEP. It's worth noting that @@ will probably see marginal use -- matrix power and matrix inversion are not common operations in number crunching code. Matrix inversion is very common in math formulas, but on a computer you almost always want to use a fused invert+multiply operation instead of inversion itself. My original draft didn't even allow '@@ -1'; I added it at the request of the symbolic math guys. In practice the main use case for @@ will probably be as a crutch for beginners before they learn about better tools like numpy.linalg.solve (which implements fused invert+multiply). Anyway, I wrote some more text for the PEP, see what you think: Rationale for specification details =================================== Choice of operator ------------------ Why ``@`` instead of some other spelling? There isn't any consensus across other programming languages about how this operator should be named [#matmul-other-langs]_; here we discuss the various options. Restricting ourselves only to symbols present on US English keyboards, the punctuation characters that don't already have a meaning in Python expression context are: ``@``, backtick, ``$``, ``!``, and ``?``. Of these options, ``@`` is clearly the best; ``!`` and ``?`` are already heavily freighted with inapplicable meanings in the programming context, backtick has been banned from Python by BDFL pronouncement (see PEP 3099), and ``$`` is uglier, even more dissimilar to ``*`` and :math:`\cdot`, and has Perl/PHP baggage. ``$`` is probably the second-best option of these, though. Symbols which are not present on US English keyboards start at a significant disadvantage (having to spend 5 minutes at the beginning of every numeric Python tutorial just going over keyboard layouts is not a hassle anyone really wants). Plus, even if we somehow overcame the typing problem, it's not clear there are any that are actually better than ``@``. Some options that have been suggested include: * U+00D7 MULTIPLICATION SIGN: ``A × B`` * U+22C5 DOT OPERATOR: ``A ⋅ B`` * U+2297 CIRCLED TIMES: ``A ⊗ B`` * U+00B0 DEGREE: ``A ° B`` What we need, though, is an operator that means "matrix multiplication, as opposed to scalar/elementwise multiplication". There is no conventional symbol for these in mathematics or programming, where these operations are usually distinguished by context. (And U+2297 CIRCLED TIMES is actually used conventionally to mean exactly the opposite: elementwise multiplication -- the "Hadamard product" -- as opposed to matrix multiplication). ``@`` at least has the virtue that it *looks* like a funny non-commutative operator; a naive user who knows maths but not programming couldn't look at ``A * B`` versus ``A × B``, or ``A * B`` versus ``A ⋅ B``, or ``A * B`` versus ``A ° B`` and guess which one is the usual multiplication, and which one is the special case. Finally, there is the option of using multi-character tokens. Some options: * Matlab uses a ``.*`` operator. Aside from being visually confusable with ``*``, this would be a terrible choice for us because in Matlab, ``*`` means matrix multiplication and ``.*`` means elementwise multiplication, so using ``.*`` for matrix multiplication would make us exactly backwards from what Matlab users expect. * APL apparently used ``+.×``, which by combining a multi-character token, confusing attribute-access-like . syntax, and a unicode character, ranks somewhere below U+2603 SNOWMAN on our candidate list. If we like the idea of combining addition and multiplication operators as being evocative of how matrix multiplication actually works, then something like ``+*`` could be used -- though this may be too easy to confuse with ``*+``, which is just multiplication combined with the unary ``+`` operator. * PEP 211 suggested ``~*`` and ``~**``. This has the downside that it sort of suggests that there is a unary ``*`` operator that is being combined with unary ``~``, but it could work. * R uses ``%*%`` for matrix multiplication. In R this forms part of a general extensible infix system in which all tokens of the form ``%foo%`` are user-defined binary operators. We could steal the token without stealing the system. * Some other plausible candidates that have been suggested: ``><`` (= ascii drawing of the multiplication sign ×); the footnote operators ``[*]`` and ``[**]`` or ``|*|`` and ``|**|`` (but when used in context, the use of vertical grouping symbols tends to recreate the nested parentheses visual clutter that was noted as one of the major downsides of the function syntax we're trying to get away from); ``^*`` and ``^^``. So, it doesn't matter much, but ``@`` seems as good or better than any of the alternatives: * It's a friendly character that Pythoneers are already used to typing in decorators, but the decorator usage and the math expression usage are sufficiently dissimilar that it would be hard to confuse them in practice. * It's widely accessible across keyboard layouts (and thanks to its use in email addresses, this is true even of weird keyboards like those in phones). * It's round like ``*`` and :math:`\cdot`. * The mATrices mnemonic is cute. * The use of a single-character token reduces the line-noise effect, and makes ``@@`` possible, which is a nice bonus. * The swirly shape is reminiscent of the simultaneous sweeps over rows and columns that define matrix multiplication * Its asymmetry is evocative of its non-commutative nature. -- Nathaniel J. Smith Postdoctoral researcher - Informatics - University of Edinburgh http://vorpus.org
- Previous message: [Python-ideas] [RFC] draft PEP: Dedicated infix operators for matrix multiplication and matrix power
- Next message: [Python-ideas] [RFC] draft PEP: Dedicated infix operators for matrix multiplication and matrix power
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-ideas mailing list