Double "at" operator for matmul exponentiation

Python has the "star" ("*") operator for multiplication. In the context of collections it is supposed to mean element-wise multiplication. Its associated operator is __mul__. It also has the double star ("**") operator for exponentiation, which is repeated multiplication. Its associated operator is __exp__.In addition to that Python has the "at" ("@") operator for multiplication. In the context of collections it should mean linear product, like matrix times a matrix, or matrix times vector. Its associated method is __matmul__.For completeness we should now have the exponentiation operator meaning repeated application of the "at" operator. Its method could me __matexp__.

Every Python idea that has ever been proposed "for the sake of completeness" has been rejected... at least in the 24 years I've been following such closely. Do you have an actual compelling use case? An abstract symmetry isn't going to do it. On Wed, Jul 5, 2023 at 6:17 AM <haael@interia.pl> wrote:
-- The dead increasingly dominate and strangle both the living and the not-yet born. Vampiric capital and undead corporate persons abuse the lives and control the thoughts of homo faber. Ideas, once born, become abortifacients against new conceptions.

On Wed, 5 Jul 2023 at 11:18, <haael@interia.pl> wrote:
This was discussed at the time of the PEP that introduced matmul: https://peps.python.org/pep-0465/#non-definition-of-matrix-power Quote: """ Earlier versions of this PEP also proposed a matrix power operator, @@, analogous to **. But on further consideration, it was decided that the utility of this was sufficiently unclear that it would be better to leave it out for now, and only revisit the issue if – once we have more experience with @ – it turns out that @@ is truly missed. """ It has been nearly 10 years which I guess is enough time to revisit but most likely the numpy-discussion mailing list is the place to start that discussion: https://mail.python.org/mailman3/lists/numpy-discussion.python.org/ I think that the original authors wanted @@ and also other operators. At the time there had been previous more ambitious PEPs proposing many more operators or custom operators but those were rejected at least partly for being too broad. As I remember it there was a conscious effort to make PEP 465 as minimal as possible just to make sure that at least the @ operator got accepted. Matrix powers are not as widely used as matrix multiplication and probably the most common use would be M@@-1 as a strange looking version of M^-1 which would otherwise be spelled as np.linalg.inv(M). It is usually a bad idea to compute matrix inverses though (np.linalg.solve(a, b) is both faster and more accurate than np.linalg.inv(a)*b). Matlab uses left and right division like a\b and a/b for this but NumPy etc already define a/b to mean elementwise division and then having a new operator a\b mean something completely different from a/b might be confusing. I think that the people who would have wanted to push forward with things like this have probably reduced the scope of what seems possible to the extent that the only thing left to do is to possibly add @@. If that is all that is on the table then it possibly does not have enough value to be worth the effort of a language change. On the other hand it is a relatively small change since @ is already added. -- Oscar

None of the other repeated infix operators follow the same "repeated application" relation that * and ** have, i.e. // isn't repeated division, << and >> aren't repeated inequality comparisons (whathever that may be), and == isn't repeated assignment.

From perspective of calculation time of matrix multiplications Infix operators is a reasonable solution to define a subset of your own. https://doc.sagemath.org/html/en/reference/misc/sage/misc/decorators.html#sa... The problem is that if one implements it, there has to be a substitution at the expense of loosing a default operator. In scientific libraries this isn't great as all existing operators tend to be used. What I would alternatively propose is to introduce a couple of (meaningless operators), so that library developers can make use of them as they wish. What characters aren't used? “$, ?, `” (or are they?). A $pow$ 3 - meh A ?pow? 3 - looks ok. The question mark is appropriately marking ambiguous/implementation dependent meaning. A `pow` 3 - looks good A @@ 3 - doesn’t look too great... A.pow(3) - nice If I was lacking just one operator (especially in such case where different algorithms can be used), A.pow(-1, inv_type=‘LU') feels most convenient given flexibility of arguments. If I was to go heavy on operators in matrix algebra or defining some sort of new syntax, then @@ wouldn’t help anyways - it’s just one (and fairly awful looking).

On Thu, 6 Jul 2023 at 04:02, Dom Grigonis <dom.grigonis@gmail.com> wrote:
What I would alternatively propose is to introduce a couple of (meaningless operators), so that library developers can make use of them as they wish. What characters aren't used? “$, ?, `” (or are they?).
What should their precedences be? Operators have to be given that, at least. Unfortunately, whatever precedence you choose, it's going to be awkwardly wrong for at least some potential use-cases. That said, though, there are some pretty cool packages out there that create arbitrary operators. Some of them take advantage of multiple operators to allow multiple effective precedences. Consider for example: https://pypi.org/project/infix/ ChrisA

a + b + c ?op? a / b / c a + b + (c ?op? a) / b / c As this in theory is the highest level operator, given it would mostly be used in framework level packages, it’s precedence naturally begs for the lowest status. But yes, then this would limit the operator to certain use cases. E.g. it wouldn’t be suitable to solve the problem of OP.
It would be cleaner approach, currently `Infix` feels a bit hacky to me due to reusing of operators, which have another purpose.

Every Python idea that has ever been proposed "for the sake of completeness" has been rejected... at least in the 24 years I've been following such closely. Do you have an actual compelling use case? An abstract symmetry isn't going to do it. On Wed, Jul 5, 2023 at 6:17 AM <haael@interia.pl> wrote:
-- The dead increasingly dominate and strangle both the living and the not-yet born. Vampiric capital and undead corporate persons abuse the lives and control the thoughts of homo faber. Ideas, once born, become abortifacients against new conceptions.

On Wed, 5 Jul 2023 at 11:18, <haael@interia.pl> wrote:
This was discussed at the time of the PEP that introduced matmul: https://peps.python.org/pep-0465/#non-definition-of-matrix-power Quote: """ Earlier versions of this PEP also proposed a matrix power operator, @@, analogous to **. But on further consideration, it was decided that the utility of this was sufficiently unclear that it would be better to leave it out for now, and only revisit the issue if – once we have more experience with @ – it turns out that @@ is truly missed. """ It has been nearly 10 years which I guess is enough time to revisit but most likely the numpy-discussion mailing list is the place to start that discussion: https://mail.python.org/mailman3/lists/numpy-discussion.python.org/ I think that the original authors wanted @@ and also other operators. At the time there had been previous more ambitious PEPs proposing many more operators or custom operators but those were rejected at least partly for being too broad. As I remember it there was a conscious effort to make PEP 465 as minimal as possible just to make sure that at least the @ operator got accepted. Matrix powers are not as widely used as matrix multiplication and probably the most common use would be M@@-1 as a strange looking version of M^-1 which would otherwise be spelled as np.linalg.inv(M). It is usually a bad idea to compute matrix inverses though (np.linalg.solve(a, b) is both faster and more accurate than np.linalg.inv(a)*b). Matlab uses left and right division like a\b and a/b for this but NumPy etc already define a/b to mean elementwise division and then having a new operator a\b mean something completely different from a/b might be confusing. I think that the people who would have wanted to push forward with things like this have probably reduced the scope of what seems possible to the extent that the only thing left to do is to possibly add @@. If that is all that is on the table then it possibly does not have enough value to be worth the effort of a language change. On the other hand it is a relatively small change since @ is already added. -- Oscar

None of the other repeated infix operators follow the same "repeated application" relation that * and ** have, i.e. // isn't repeated division, << and >> aren't repeated inequality comparisons (whathever that may be), and == isn't repeated assignment.

From perspective of calculation time of matrix multiplications Infix operators is a reasonable solution to define a subset of your own. https://doc.sagemath.org/html/en/reference/misc/sage/misc/decorators.html#sa... The problem is that if one implements it, there has to be a substitution at the expense of loosing a default operator. In scientific libraries this isn't great as all existing operators tend to be used. What I would alternatively propose is to introduce a couple of (meaningless operators), so that library developers can make use of them as they wish. What characters aren't used? “$, ?, `” (or are they?). A $pow$ 3 - meh A ?pow? 3 - looks ok. The question mark is appropriately marking ambiguous/implementation dependent meaning. A `pow` 3 - looks good A @@ 3 - doesn’t look too great... A.pow(3) - nice If I was lacking just one operator (especially in such case where different algorithms can be used), A.pow(-1, inv_type=‘LU') feels most convenient given flexibility of arguments. If I was to go heavy on operators in matrix algebra or defining some sort of new syntax, then @@ wouldn’t help anyways - it’s just one (and fairly awful looking).

On Thu, 6 Jul 2023 at 04:02, Dom Grigonis <dom.grigonis@gmail.com> wrote:
What I would alternatively propose is to introduce a couple of (meaningless operators), so that library developers can make use of them as they wish. What characters aren't used? “$, ?, `” (or are they?).
What should their precedences be? Operators have to be given that, at least. Unfortunately, whatever precedence you choose, it's going to be awkwardly wrong for at least some potential use-cases. That said, though, there are some pretty cool packages out there that create arbitrary operators. Some of them take advantage of multiple operators to allow multiple effective precedences. Consider for example: https://pypi.org/project/infix/ ChrisA

a + b + c ?op? a / b / c a + b + (c ?op? a) / b / c As this in theory is the highest level operator, given it would mostly be used in framework level packages, it’s precedence naturally begs for the lowest status. But yes, then this would limit the operator to certain use cases. E.g. it wouldn’t be suitable to solve the problem of OP.
It would be cleaner approach, currently `Infix` feels a bit hacky to me due to reusing of operators, which have another purpose.
participants (6)
-
Chris Angelico
-
David Mertz, Ph.D.
-
Dom Grigonis
-
haael@interia.pl
-
Joren Hammudoglu
-
Oscar Benjamin