First off, to start with a funny anecdote, I remember working with
some of the early Sage devs way back in the day optimizing matrix
multiplication and we were baffled by the fact that numpy somehow
managed to have O(n^2) behavior into the thousand by thousand matrix
range :).

More serious responses below.

On Sun, Mar 9, 2014 at 5:51 PM, Nathaniel Smith <n...@pobox.com> wrote:
> On Mon, Mar 10, 2014 at 12:09 AM, Simon King <simon.k...@uni-jena.de> wrote:
>> Hi Nathaniel,
>>
>> are you sure that you talk about actual matrices? Or do you just talk
>> about 2-dimensional arrays?
>
> Sure -- this is a useful distinction, and as far as it goes, I'm
> talking about arrays. But people do in fact want to do the operation
> commonly referred to as "matrix multiplication" when working with
> arrays, whether we like it or not. Many many people. Github code
> search produces >23,000 Python files containing the string "np.dot",
> and every one of those is a violation of the "keep matrices and
> arrays" separate principle. So this is the reality we live in...

I think this arrays vs. matrices is *the* key distinction to keep in
mind. Element-wise is the only sane way to extend binary operations to
arrays of arbitrary dimension.

By this logic, we should define multiplication of polynomials
element-wise as well: after all polynomials are typically defined as
arrays of coefficients....

>> By the way, how could your PEP possibly be relevant to Python? IIRC,
>> there neither is a matrix type nor an array type in Python, thus, it
>> makes no sense whatsoever to theoretise about special symbols for matrix
>> multiplication and component-wise action on arrays in *Python*.
>
> There are a dozen or more array and matrix types in Python. I use them
> all the time. So do thousands of other people. You don't download them
> from http://python.org, but this doesn't make them nonsense...
>
>> Such discussion sure makes sense in a CAS, though..
>>
>> On 2014-03-09, Nathaniel Smith <n...@pobox.com> wrote:
>>> ...
>>> R alsos use * for elementwise mul. And really, it does work fine and
>>> is useful in many application areas, I promise! :-) I've sent similar
>>> heads-up emails to 13 projects now, and so far you guys are the only
>>> ones who have blinked at this part;
>>
>> Quite bizarre indeed, as I'd thought that your suggestion will seem rather
>> odd to most mathematicians and computer scientists.
>
> Well, not ones who crunch numbers all day :-). It's got a long history
> -- e.g. Fortran also uses * to mean elementwise mul.
>
>>> Even * is pretty
>>> arbitrary the first time you see it -- real mathematical notation uses
>>> \cdot or occasionally \times, not \star -- but we forget this because
>>> we already learned it a while ago :-).
>>
>> In mathematics, a lot of different multiplication symbols are in use.
>> For example, usually \cdot denotes pointwise multiplication, whereas
>> \star denotes convolution and \circ denotes composition, and there
>> is also cartesian product \times and tensor product \otimes. In
>> principal, all these operations can occur at the same time, thus, there
>> is no way around using a variety of symbols, to avoid confusion.
>>
>> Thus, it would certainly be a reasonable PEP to provide a framework in
>> Python to define custom infix operators (say, operator.compose), by
>> providing a character (say: '@') and the name of a custom "magical
>> method" (say: '__composition__') that is called on the operator's
>> arguments, in the same way as operator.mul uses '*' and results in
>> calling '__mul__'.
>
> I do not believe that it is possible to write such a PEP that would be
> acceptable to the broader Python community. (I don't even think I
> could come up with such a PEP that I would accept if I were BDFL.)
> It's a huge change to how Python works, and runs into a lot of
> practical problems (defining precedence, defining scoping, creating
> nasty couplings between parse time and eval time, etc.).
>
> That's just my best judgement, though; if someone comes along with a
> convincing proposal then I'll certainly advocate it.
>
>> However, in all algebraic textbooks I am aware of, \cdot is consistently
>> used to denote...
>> - multiplication in fields,
>> - the componentwise action of a field on vectors resp. matrices, aka
>>   scalar multiplication,
>> - the dot product of vectors (resulting in a field element)
>> - matrix multiplication,
>> - generally multiplication in a ring, unless different kinds of
>>   multiplication occur
>>
>> It may seem natural to multiply two 2-dimensional ARRAYS component-wise.
>> However, if you have MATRICES that deserve such a title (say, they
>> encode a linear map) then "Matrix \cdot Matrix" clearly is matrix
>> multiplication and nothing else.
>>
>> Python does not know about rings and vector spaces, whereas Sage does:
>> Sage uses '*' for multiplication in rings and for module actions. In
>> particular, by consistency, Sage must use '*' to denote multiplication
>> of square matrices (since this is multiplication in a matrix ring)
>>
>> Python uses * to denote multiplication of numbers, which is \cdot in
>> textbooks. Hence, according to the "principle of least surprise", one
>> has to use * for what is commonly denoted by \cdot in textbooks. And
>> this includes matrix multiplication.
>
> Sure, fair enough. If you're lucky enough to be dealing only with pure
> mathematical matrices, then the problem this PEP is addressing doesn't
> arise. Practical number crunching OTOH isn't so pretty, but it is
> useful :-).

There are certainly times when one wants to work with arrays like this
in Sage, and it's perfectly fine to invoke numpy to do so. In general,
however, x*y (where x and y are of the same type, or coercible to the
same type) denotes multiplication as defined in the parent (Group,
Ring, Monoid, whatever) of x and y. This isn't special to matrices: it
applies to rationals, algebraic numbers, polynomials, permutations,
etc. The * operator is also used to denote an action, e.g. on scalar
multiplication of a matrix, a matrix acting on a vector, or the
integer ring on a abelian group like an elliptic curve. Pretty much
whatever would be represented on the blackboard by a \cdot or simply
placing symbols adjacent to each other.

IMHO it seems odd to try to define a new infix operator that
specifically has "matrix multiplication" semantics. That seems out of
the domain of the Python language. If it were to be accepted, there's
no way Sage would start using * to do element-wise multiplication of
matrices.

- Robert

-- 
You received this message because you are subscribed to the Google Groups 
"sage-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-devel+unsubscr...@googlegroups.com.
To post to this group, send email to sage-devel@googlegroups.com.
Visit this group at http://groups.google.com/group/sage-devel.
For more options, visit https://groups.google.com/d/optout.

Reply via email to