Re: [Numpy-discussion] [RFC] should we argue for a matrix power operator, @@?

2014-03-15 Thread Christophe Bal
Hello.

Maybe a solution would be to not see @ and @@ only from the matrix point of
view.

Why ? The philosophy of Python is to give total control of the infix
operators +, * and ** for example via the magic methods. So it can be also
the case for @ and @@ that could be use for something else
that matrix@@int.

So what we can expect from A@@B@@C. I will say that is the same as a**b**c
because a human goes from top to down (but this is not a general convention
in CAS).

Ok guy but what can we do for matrix@@matrix@@matrix. Just raises an
error. The programmer has the possibility to use @@ as ** but it has to
take care of the meaning regarding to the types of the objects. This is for
example what we expect for matrix@@pi even if we mathematically can give
a meaning to that for some matrices.

Do not forget also that a direct computation of the inverse of a matrice is
a complicated things, and that integer power of matrices have to be
cleverly build, but I'm sure that everyones here know that.

*So standard Python can...*

   - only proposes multiplication of matrices,
   - and for the power of matrices, just indicates that there is a magic
   method associated to @@ and explains that regarding to the complexity of
   this problem, it will be the job of the programmer to implement it.


I think the problem from Guido's point of view is the asymmetrical type
domain for operations. All the numeric operators are from number*number
to number.

Hoping that my frenchy english is clear enough.
Chrisopthe BAL


PS: maybe a good question for Python would be to see if other operators
could be useful. For CAS, I would like to have the possibility to use f°g
for composition, even if it is more for pedagogical reason, and f°°n for
dynamical systems. But this is just a dream...


2014-03-15 6:39 GMT+01:00 Jaime Fernández del Río jaime.f...@gmail.com:

 On Fri, Mar 14, 2014 at 9:32 PM, Nathaniel Smith n...@pobox.com wrote:


 Here are the interesting use cases for @@ that I can think of:
 - 'vector @@ 2' gives the squared Euclidean length (because it's the
 same as vector @ vector). Kind of handy.
 - 'matrix @@ n' of course gives the matrix power, which is of marginal
 use but does come in handy sometimes, e.g., when looking at graph
 connectivity.
 - 'matrix @@ -1' provides a very transparent notation for translating
 textbook formulas (with all their inverses) into code. It's a bit
 unhelpful in practice, because (a) usually you should use solve(), and
 (b) 'matrix @@ -1' is actually more characters than 'inv(matrix)'. But
 sometimes transparent notation may be important. (And in some cases,
 like using numba or theano or whatever, 'matrix @@ -1 @ foo' could be
 compiled into a call to solve() anyway.)

 (Did I miss any?)


 I'm not really arguing for it, and I am not sure how, or even if, it fits
 in the general scheme. But for completeness sake, 'e @@ Matrix' is used in
 some treatments of linear systems of differential equations, where:

 dvector/dt = matrix @ vector

 would have solution

 vector = e @@ (matrix * t) @ vector_0

 I don't think it makes any sense to use it as such in the context of
 numpy, as I think it would make broadcasting undecidable. But there may be
 parallel universes where having n @@ matrix and matrix @@ n both with
 well defined, yet different meanings may make sense. It is my impression
 that in this entirely made up scenario you would want e @@ A @@ 3 to be
 evaluated as (e @@ A) @@ 3. Which probably has more to do with the fact
 that the two @@ mean different things, than with the associativity that
 repeated calls to the same @@ should have.

 Personally I couldn't care less, and if I had a vote I would let @@ rest
 for now, until we see how @ plays out.

 Jaime




 ___
 NumPy-Discussion mailing list
 NumPy-Discussion@scipy.org
 http://mail.scipy.org/mailman/listinfo/numpy-discussion


___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Robert Kern
I tend to favor tight-right. The general scheme of precedence more or
less puts heavier operations higher than lighter operations (+  *
 **) and @ is heavier than * in my mind. I think tight (either
-right or -left) has a good correspondence with current dot()
expressions, so it will make translation a bit more straightforward,
IMO.

  s * dot(A, b) == s * A @ b
  dot(s * A, b) == (s * A) @ b


On Sat, Mar 15, 2014 at 3:41 AM, Nathaniel Smith n...@pobox.com wrote:
 Hi all,

 Here's the main blocker for adding a matrix multiply operator '@' to Python:
 we need to decide what we think its precedence and associativity should be.
 I'll explain what that means so we're on the same page, and what the choices
 are, and then we can all argue about it. But even better would be if we
 could get some data to guide our decision, and this would be a lot easier if
 some of you all can help; I'll suggest some ways you might be able to do
 that.

 So! Precedence and left- versus right-associativity. If you already know
 what these are you can skim down until you see CAPITAL LETTERS.

 We all know what precedence is. Code like this:
   a + b * c
 gets evaluated as:
   a + (b * c)
 because * has higher precedence than +. It binds more tightly, as they
 say. Python's complete precedence able is here:
   http://docs.python.org/3/reference/expressions.html#operator-precedence

 Associativity, in the parsing sense, is less well known, though it's just as
 important. It's about deciding how to evaluate code like this:
   a * b * c
 Do we use
   a * (b * c)# * is right associative
 or
   (a * b) * c# * is left associative
 ? Here all the operators have the same precedence (because, uh... they're
 the same operator), so precedence doesn't help. And mostly we can ignore
 this in day-to-day life, because both versions give the same answer, so who
 cares. But a programming language has to pick one (consider what happens if
 one of those objects has a non-default __mul__ implementation). And of
 course it matters a lot for non-associative operations like
   a - b - c
 or
   a / b / c
 So when figuring out order of evaluations, what you do first is check the
 precedence, and then if you have multiple operators next to each other with
 the same precedence, you check their associativity. Notice that this means
 that if you have different operators that share the same precedence level
 (like + and -, or * and /), then they have to all have the same
 associativity. All else being equal, it's generally considered nice to have
 fewer precedence levels, because these have to be memorized by users.

 Right now in Python, every precedence level is left-associative, except for
 '**'. If you write these formulas without any parentheses, then what the
 interpreter will actually execute is:
   (a * b) * c
   (a - b) - c
   (a / b) / c
 but
   a ** (b ** c)

 Okay, that's the background. Here's the question. We need to decide on
 precedence and associativity for '@'. In particular, there are three
 different options that are interesting:

 OPTION 1 FOR @:
 Precedence: same as *
 Associativity: left
 My shorthand name for it: same-left (yes, very creative)

 This means that if you don't use parentheses, you get:
a @ b @ c  -  (a @ b) @ c
a * b @ c  -  (a * b) @ c
a @ b * c  -  (a @ b) * c

 OPTION 2 FOR @:
 Precedence: more-weakly-binding than *
 Associativity: right
 My shorthand name for it: weak-right

 This means that if you don't use parentheses, you get:
a @ b @ c  -  a @ (b @ c)
a * b @ c  -  (a * b) @ c
a @ b * c  -  a @ (b * c)

 OPTION 3 FOR @:
 Precedence: more-tightly-binding than *
 Associativity: right
 My shorthand name for it: tight-right

 This means that if you don't use parentheses, you get:
a @ b @ c  -  a @ (b @ c)
a * b @ c  -  a * (b @ c)
a @ b * c  -  (a @ b) * c

 We need to pick which of which options we think is best, based on whatever
 reasons we can think of, ideally more than hmm, weak-right gives me warm
 fuzzy feelings ;-). (In principle the other 2 possible options are
 tight-left and weak-left, but there doesn't seem to be any argument in favor
 of either, so we'll leave them out of the discussion.)

 Some things to consider:

 * and @ are actually not associative (in the math sense) with respect to
 each other, i.e., (a * b) @ c and a * (b @ c) in general give different
 results when 'a' is not a scalar. So considering the two expressions 'a * b
 @ c' and 'a @ b * c', we can see that each of these three options gives
 produces different results in some cases.

 Same-left is the easiest to explain and remember, because it's just, @
 acts like * and /. So we already have to know the rule in order to
 understand other non-associative expressions like a / b / c or a - b - c,
 and it'd be nice if the same rule applied to things like a * b @ c so we
 only had to memorize *one* rule. (Of course there's ** which uses the
 opposite rule, but I guess everyone internalized that one 

[Numpy-discussion] [ANN] OpenOpt Suite release 0.53: Stochastic programming addon now is BSD-licensed

2014-03-15 Thread Dmitrey
hi all, 
I'm glad to inform you about new OpenOpt Suite release 0.53: 

    Stochastic programming addon now is available for free 
    Some minor changes 

-- 
Regards, D. 
http://openopt.org/Dmitrey 
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [RFC] should we argue for a matrix power operator, @@?

2014-03-15 Thread Alan G Isaac
On 3/15/2014 12:32 AM, Nathaniel Smith wrote:
   I know you were worried
 about losing the .I attribute on matrices if switching to ndarrays for
 teaching -- given that ndarray will probably not get a .I attribute,
 how much would the existence of @@ -1 affect you?

Not much. Positive integer powers would be useful
(for illustrating e.g. graph theory and difference equations),
but not enough to delay the PEP.

I think NumPy should take the money and run.
Getting `@` is great.  Let's get experience with
it before deciding whether it's worth asking for `@@`.

Questions for `@@`:
- would it just be `matrix_power`, with all the restrictions?
- or would `a(10,2,2)@@-1` return an array of matrix inverses?
- etc

In the end, I'd like to see a functional implementation before
deciding on `@@`, but I would not like to see `@` delayed at all.

Congratulations,
Alan

___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Charles R Harris
I favor the weak right option.

1) Giving '*' higher precedence than `@` makes it easier, to my mind, to
parse out what is going to happen: all the element-wise multiplications,
followed by the matrix operations. I'd probably still use parenthesis for
clarity.

2) Right associative has the advantage of efficiency in many common use
cases, plus I tend to read matrix expressions from right to left.

Chuck
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] It looks like Py 3.5 will include a dedicated infix matrix multiply operator

2014-03-15 Thread Charles R Harris
On Fri, Mar 14, 2014 at 6:51 PM, Nathaniel Smith n...@pobox.com wrote:

 Well, that was fast. Guido says he'll accept the addition of '@' as an
 infix operator for matrix multiplication, once some details are ironed
 out:
   https://mail.python.org/pipermail/python-ideas/2014-March/027109.html
   http://legacy.python.org/dev/peps/pep-0465/

 Specifically, we need to figure out whether we want to make an
 argument for a matrix power operator (@@), and what
 precedence/associativity we want '@' to have. I'll post two separate
 threads to get feedback on those in an organized way -- this is just a
 heads-up.


Surprisingly little discussion on python-ideas, or so it seemed to me.
Guido came out in favor less than halfway through. Congratulations on
putting together a successful proposal, many of us had given up on ever
seeing a matrix multiplication operator.

Chuck
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [RFC] should we argue for a matrix power operator, @@?

2014-03-15 Thread Charles R Harris
On Fri, Mar 14, 2014 at 10:32 PM, Nathaniel Smith n...@pobox.com wrote:

 Hi all,

 Here's the second thread for discussion about Guido's concerns about
 PEP 465. The issue here is that PEP 465 as currently written proposes
 two new operators, @ for matrix multiplication and @@ for matrix power
 (analogous to * and **):
   http://legacy.python.org/dev/peps/pep-0465/

 The main thing we care about of course is @; I pushed for including @@
 because I thought it was nicer to have than not, and I thought the
 analogy between * and ** might make the overall package more appealing
 to Guido's aesthetic sense.

 It turns out I was wrong :-). Guido is -0 on @@, but willing to be
 swayed if we think it's worth the trouble to make a solid case.

 Note that question now is *not*, how will @@ affect the reception of
 @. @ itself is AFAICT a done deal, regardless of what happens with @@.
 For this discussion let's assume @ can be taken for granted, and that
 we can freely choose to either add @@ or not add @@ to the language.
 The question is: which do we think makes Python a better language (for
 us and in general)?

 Some thoughts to start us off:

 Here are the interesting use cases for @@ that I can think of:
 - 'vector @@ 2' gives the squared Euclidean length (because it's the
 same as vector @ vector). Kind of handy.
 - 'matrix @@ n' of course gives the matrix power, which is of marginal
 use but does come in handy sometimes, e.g., when looking at graph
 connectivity.
 - 'matrix @@ -1' provides a very transparent notation for translating
 textbook formulas (with all their inverses) into code. It's a bit
 unhelpful in practice, because (a) usually you should use solve(), and
 (b) 'matrix @@ -1' is actually more characters than 'inv(matrix)'. But
 sometimes transparent notation may be important. (And in some cases,
 like using numba or theano or whatever, 'matrix @@ -1 @ foo' could be
 compiled into a call to solve() anyway.)

 (Did I miss any?)

 In practice it seems to me that the last use case is the one that's
 might matter a lot practice, but then again, it might not -- I'm not
 sure. For example, does anyone who teaches programming with numpy have
 a feeling about whether the existence of '@@ -1' would make a big
 difference to you and your students? (Alan? I know you were worried
 about losing the .I attribute on matrices if switching to ndarrays for
 teaching -- given that ndarray will probably not get a .I attribute,
 how much would the existence of @@ -1 affect you?)

 On a more technical level, Guido is worried about how @@'s precedence
 should work (and this is somewhat related to the other thread about
 @'s precedence and associativity, because he feels that if we end up
 giving @ and * different precedence, then that makes it much less
 clear what to do with @@, and reduces the strength of the */**/@/@@
 analogy). In particular, if we want to argue for @@ then we'll need to
 figure out what expressions like
a @@ b @@ c
 and
a ** b @@ c
 and
a @@ b ** c
 should do.

 A related question is what @@ should do if given an array as its right
 argument. In the current PEP, only integers are accepted, which rules
 out a bunch of the more complicated cases like a @@ b @@ c (at least
 assuming @@ is right-associative, like **, and I can't see why you'd
 want anything else). OTOH, in the brave new gufunc world, it
 technically would make sense to define @@ as being a gufunc with
 signature (m,m),()-(m,m), and the way gufuncs work this *would* allow
 the power to be an array -- for example, we'd have:

mat = randn(m, m)
pow = range(n)
result = gufunc_matrix_power(mat, pow)
assert result.shape == (n, m, m)
for i in xrange(n):
assert np.all(result[i, :, :] == mat ** i)

 In this case, a @@ b @@ c would at least be a meaningful expression to
 write. OTOH it would be incredibly bizarre and useless, so probably
 no-one would ever write it.

 As far as these technical issues go, my guess is that the correct rule
 is that @@ should just have the same precedence and the same (right)
 associativity as **, and in practice no-one will ever write stuff like
 a @@ b @@ c. But if we want to argue for @@ we need to come to some
 consensus or another here.

 It's also possible the answer is ugh, these issues are too
 complicated, we should defer this until later when we have more
 experience with @ and gufuncs and stuff. After all, I doubt anyone
 else will swoop in and steal @@ to mean something else! OTOH, if e.g.
 there's a strong feeling that '@@ -1' will make a big difference in
 pedagogical contexts, then putting that off for years might be a
 mistake.


I don't have a strong feeling either way on '@@' . Matrix inverses are
pretty common in matrix expressions, but I don't know that the new operator
offers much advantage over a function call. The positive integer powers
might be useful in some domains, as others have pointed out, but
computational practice one would tend to factor 

Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Robert Kern
On Sat, Mar 15, 2014 at 2:49 PM, Charles R Harris
charlesr.har...@gmail.com wrote:

 I favor the weak right option.

 1) Giving '*' higher precedence than `@` makes it easier, to my mind, to
 parse out what is going to happen: all the element-wise multiplications,
 followed by the matrix operations. I'd probably still use parenthesis for
 clarity.

It seems to me that 'tight' gives the same benefit. Any reasoning for
the preference of 'weak' over 'tight'?

-- 
Robert Kern
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [RFC] should we argue for a matrix power operator, @@?

2014-03-15 Thread Olivier Delalleau
2014-03-15 11:18 GMT-04:00 Charles R Harris charlesr.har...@gmail.com:




 On Fri, Mar 14, 2014 at 10:32 PM, Nathaniel Smith n...@pobox.com wrote:

 Hi all,

 Here's the second thread for discussion about Guido's concerns about
 PEP 465. The issue here is that PEP 465 as currently written proposes
 two new operators, @ for matrix multiplication and @@ for matrix power
 (analogous to * and **):
   http://legacy.python.org/dev/peps/pep-0465/

 The main thing we care about of course is @; I pushed for including @@
 because I thought it was nicer to have than not, and I thought the
 analogy between * and ** might make the overall package more appealing
 to Guido's aesthetic sense.

 It turns out I was wrong :-). Guido is -0 on @@, but willing to be
 swayed if we think it's worth the trouble to make a solid case.

 Note that question now is *not*, how will @@ affect the reception of
 @. @ itself is AFAICT a done deal, regardless of what happens with @@.
 For this discussion let's assume @ can be taken for granted, and that
 we can freely choose to either add @@ or not add @@ to the language.
 The question is: which do we think makes Python a better language (for
 us and in general)?

 Some thoughts to start us off:

 Here are the interesting use cases for @@ that I can think of:
 - 'vector @@ 2' gives the squared Euclidean length (because it's the
 same as vector @ vector). Kind of handy.
 - 'matrix @@ n' of course gives the matrix power, which is of marginal
 use but does come in handy sometimes, e.g., when looking at graph
 connectivity.
 - 'matrix @@ -1' provides a very transparent notation for translating
 textbook formulas (with all their inverses) into code. It's a bit
 unhelpful in practice, because (a) usually you should use solve(), and
 (b) 'matrix @@ -1' is actually more characters than 'inv(matrix)'. But
 sometimes transparent notation may be important. (And in some cases,
 like using numba or theano or whatever, 'matrix @@ -1 @ foo' could be
 compiled into a call to solve() anyway.)

 (Did I miss any?)

 In practice it seems to me that the last use case is the one that's
 might matter a lot practice, but then again, it might not -- I'm not
 sure. For example, does anyone who teaches programming with numpy have
 a feeling about whether the existence of '@@ -1' would make a big
 difference to you and your students? (Alan? I know you were worried
 about losing the .I attribute on matrices if switching to ndarrays for
 teaching -- given that ndarray will probably not get a .I attribute,
 how much would the existence of @@ -1 affect you?)

 On a more technical level, Guido is worried about how @@'s precedence
 should work (and this is somewhat related to the other thread about
 @'s precedence and associativity, because he feels that if we end up
 giving @ and * different precedence, then that makes it much less
 clear what to do with @@, and reduces the strength of the */**/@/@@
 analogy). In particular, if we want to argue for @@ then we'll need to
 figure out what expressions like
a @@ b @@ c
 and
a ** b @@ c
 and
a @@ b ** c
 should do.

 A related question is what @@ should do if given an array as its right
 argument. In the current PEP, only integers are accepted, which rules
 out a bunch of the more complicated cases like a @@ b @@ c (at least
 assuming @@ is right-associative, like **, and I can't see why you'd
 want anything else). OTOH, in the brave new gufunc world, it
 technically would make sense to define @@ as being a gufunc with
 signature (m,m),()-(m,m), and the way gufuncs work this *would* allow
 the power to be an array -- for example, we'd have:

mat = randn(m, m)
pow = range(n)
result = gufunc_matrix_power(mat, pow)
assert result.shape == (n, m, m)
for i in xrange(n):
assert np.all(result[i, :, :] == mat ** i)

 In this case, a @@ b @@ c would at least be a meaningful expression to
 write. OTOH it would be incredibly bizarre and useless, so probably
 no-one would ever write it.

 As far as these technical issues go, my guess is that the correct rule
 is that @@ should just have the same precedence and the same (right)
 associativity as **, and in practice no-one will ever write stuff like
 a @@ b @@ c. But if we want to argue for @@ we need to come to some
 consensus or another here.

 It's also possible the answer is ugh, these issues are too
 complicated, we should defer this until later when we have more
 experience with @ and gufuncs and stuff. After all, I doubt anyone
 else will swoop in and steal @@ to mean something else! OTOH, if e.g.
 there's a strong feeling that '@@ -1' will make a big difference in
 pedagogical contexts, then putting that off for years might be a
 mistake.


 I don't have a strong feeling either way on '@@' . Matrix inverses are
 pretty common in matrix expressions, but I don't know that the new operator
 offers much advantage over a function call. The positive integer powers
 might be useful in some domains, as 

Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Robert Kern
On Sat, Mar 15, 2014 at 11:44 AM, Robert Kern robert.k...@gmail.com wrote:
 I tend to favor tight-right. The general scheme of precedence more or
 less puts heavier operations higher than lighter operations (+  *
  **) and @ is heavier than * in my mind. I think tight (either
 -right or -left) has a good correspondence with current dot()
 expressions, so it will make translation a bit more straightforward,
 IMO.

   s * dot(A, b) == s * A @ b
   dot(s * A, b) == (s * A) @ b

I'm not sure if this is a convincing argument, but I'll throw it out
there: in most of my programming fonts, @ is a bigger, more visually
salient character than *, so in any expression that mixes the two, my
visual system is going to end up grouping the @-connected terms
anyways.

-- 
Robert Kern
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] GSoC project: draft of proposal

2014-03-15 Thread Leo Mao
Because of the license problem, I think I will choose Yeppp as a default
backend.
And if time allows, maybe I can implement other bindings. (Vc library)

Also I found that sleef library is in public domain. But it seems that it
only provides fast math function,
 not vectorized math function. So I am not sure if it can be used in this
project.

Finally, if there are any suggestions for my proposal, please point out.
I will appreciate your suggestions.

Thanks.

Regards,
Leo Mao
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Charles R Harris
On Sat, Mar 15, 2014 at 9:58 AM, Robert Kern robert.k...@gmail.com wrote:

 On Sat, Mar 15, 2014 at 2:49 PM, Charles R Harris
 charlesr.har...@gmail.com wrote:
 
  I favor the weak right option.
 
  1) Giving '*' higher precedence than `@` makes it easier, to my mind, to
  parse out what is going to happen: all the element-wise multiplications,
  followed by the matrix operations. I'd probably still use parenthesis for
  clarity.

 It seems to me that 'tight' gives the same benefit. Any reasoning for
 the preference of 'weak' over 'tight'?


Two other reasons come to mind. First, '*' is right associative, so I think
it is nicer to first view the expression as parsed into blocks separated by
'@', which act somewhat like parenthesis at that point, and then evaluate
the blocks. Second, and somewhat weaker, it might make it easier to track
how arrays are broadcast.

Chuck
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Charles R Harris
Oops, make that '*' is *left* associative.

snip

Chuck
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Robert Kern
On Sat, Mar 15, 2014 at 4:40 PM, Charles R Harris
charlesr.har...@gmail.com wrote:

 On Sat, Mar 15, 2014 at 9:58 AM, Robert Kern robert.k...@gmail.com wrote:

 On Sat, Mar 15, 2014 at 2:49 PM, Charles R Harris
 charlesr.har...@gmail.com wrote:
 
  I favor the weak right option.
 
  1) Giving '*' higher precedence than `@` makes it easier, to my mind, to
  parse out what is going to happen: all the element-wise multiplications,
  followed by the matrix operations. I'd probably still use parenthesis
  for
  clarity.

 It seems to me that 'tight' gives the same benefit. Any reasoning for
 the preference of 'weak' over 'tight'?


 Two other reasons come to mind. First, '*' is right associative, so I think
 it is nicer to first view the expression as parsed into blocks separated by
 '@', which act somewhat like parenthesis at that point, and then evaluate
 the blocks.

Again, I think tight does the same amount of separation, just with
blocks of matrix multiplication broken up by elementwise
multiplication; this is just an argument against 'same', not for
'weak' over 'tight'. As I mentioned elsewhere, my visual system seems
to break things up with @-tight anyways. Does it not for you?

 Second, and somewhat weaker, it might make it easier to track
 how arrays are broadcast.

I think this point is going to ultimately determine this, if we can
break down all the cases and if they actually do favor one choice over
another.

-- 
Robert Kern
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Alexander Belopolsky
On Fri, Mar 14, 2014 at 11:41 PM, Nathaniel Smith n...@pobox.com wrote:

 Here's the main blocker for adding a matrix multiply operator '@' to
 Python: we need to decide what we think its precedence and associativity
 should be.


I am not ready to form my own opinion, but I hope the following will help
shaping the discussion.

Currently, [1], Python operator precedence is

+, -Addition and subtraction*, /, //, %Multiplication, division, remainder
[5] http://docs.python.org/3/reference/expressions.html#id20+x, -x,
~xPositive,
negative, bitwise NOT**Exponentiation
[6]http://docs.python.org/3/reference/expressions.html#id21
x[index], x[index:index], x(arguments...), x.attributeSubscription,
slicing, call, attribute reference

We need to decide whether @ belongs to one of the existing row or deserves
one of its own.

The associativity debate is one of those debates [2] where there is no
right answer.  Guido has very wisely left it for the numeric community to
decide.  I would start with surveying the prior art of using right
associativity and the reasons it was chosen and see if those reasons apply.
 (An example of a choice made for wrong reasons is our decimal system.  We
write our numbers backwards - from high to low place value - only because
we took them from people who write text from right to left.  As a result,
computer parsers have to skip to the last or count the number of digits
before they can start evaluating the number.)

Here is the start:

1. APL uses right to left associativity for all operators and all operators
have the same precedence.
2. Exponentiation operator is right associative in most languages with
MATLAB being a notable exception.


[1] http://docs.python.org/3/reference/expressions.html#evaluation-order
[2] http://en.wikipedia.org/wiki/Lilliput_and_Blefuscu
[3] http://www.tcl.tk/cgi-bin/tct/tip/274.html
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Nathaniel Smith
On Sat, Mar 15, 2014 at 3:41 AM, Nathaniel Smith n...@pobox.com wrote:
 Hi all,

 Here's the main blocker for adding a matrix multiply operator '@' to Python:
 we need to decide what we think its precedence and associativity should be.

Another data point that might be useful:

Matlab: same-left

R: tight-left

IDL: same-left

GAUSS: same-left (IIUC -- any GAUSS experts please correct me if I
misunderstood the fine manual)

Mathematica: instead of having an associativity, a @ b @ c gets
converted into mdot([a, b, c])

-- 
Nathaniel J. Smith
Postdoctoral researcher - Informatics - University of Edinburgh
http://vorpus.org
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Joe Kington
On Sat, Mar 15, 2014 at 1:28 PM, Nathaniel Smith n...@pobox.com wrote:

 On Sat, Mar 15, 2014 at 3:41 AM, Nathaniel Smith n...@pobox.com wrote:
  Hi all,
 
  Here's the main blocker for adding a matrix multiply operator '@' to
 Python:
  we need to decide what we think its precedence and associativity should
 be.

 Another data point that might be useful:

 Matlab: same-left


 R: tight-left



I was going to ask this earlier, but I was worried I was missing something
major.

Why was tight-left not an option?

This means that if you don't use parentheses, you get:
   a @ b @ c  -  (a @ b) @ c
   a * b @ c  -  a * (b @ c)
   a @ b * c  -  (a @ b) * c

In my (very inexperienced) opinion, it seems like the most intuitive
option.

Cheers,
-Joe


 IDL: same-left

 GAUSS: same-left (IIUC -- any GAUSS experts please correct me if I
 misunderstood the fine manual)

 Mathematica: instead of having an associativity, a @ b @ c gets
 converted into mdot([a, b, c])

 --
 Nathaniel J. Smith
 Postdoctoral researcher - Informatics - University of Edinburgh
 http://vorpus.org
 ___
 NumPy-Discussion mailing list
 NumPy-Discussion@scipy.org
 http://mail.scipy.org/mailman/listinfo/numpy-discussion

___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Nathaniel Smith
Hi Chris,

On Sat, Mar 15, 2014 at 4:15 AM, Chris Laumann chris.laum...@gmail.com wrote:
 Hi all,

 Let me preface my two cents by saying that I think the best part of @ being
 accepted is the potential for deprecating the matrix class — the syntactic
 beauty of infix for matrix multiply is a nice side effect IMHO :) This may
 be why my basic attitude is:

 I don’t think it matters very much but I would vote (weakly) for weak-right.
 Where there is ambiguity, I suspect most practitioners will just put in
 parentheses anyway — especially with combinations of * and @, where I don’t
 think there is a natural intuitive precedence relationship. At least,
 element-wise multiplication is very rare in math/physics texts as an
 explicitly defined elementary operation so I’d be surprised if anybody had a
 strong intuition about the precedence of the ‘*’ operator. And the binding
 order doesn’t matter if it is scalar multiplication.

It doesn't matter and no-one has strong intuitions are generally
arguments for same-left, since that allows everyone to reason about @
in the same way they reason about all of Python's operators.

 I have quite a bit of code with large matrices where the order of
 matrix-vector multiplies is an important optimization and I would certainly
 have a few simpler looking expressions for op @ op @ vec, hence the weak
 preference for right-associativity. That said, I routinely come across
 situations where the optimal matrix multiplication order is more complicated
 than can be expressed as left-right or right-left (because some matrices
 might be diagonal, CSR or CSC), which is why the preference is only weak. I
 don’t see a down-side in the use-case that it is actually associative (as in
 matrix-matrix-vector).

Would you mind taking a more systematic look through this code, or
sharing some examples so the rest of us can look? Certainly have a
few simpler looking expressions is a good start, but when we're
talking about changing the grammar of one of the most popular
programming languages in the world it seems worth the effort to gather
some more careful data :-).

-n

-- 
Nathaniel J. Smith
Postdoctoral researcher - Informatics - University of Edinburgh
http://vorpus.org
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Nathaniel Smith
On Sat, Mar 15, 2014 at 6:33 PM, Joe Kington joferking...@gmail.com wrote:
 On Sat, Mar 15, 2014 at 1:28 PM, Nathaniel Smith n...@pobox.com wrote:

 On Sat, Mar 15, 2014 at 3:41 AM, Nathaniel Smith n...@pobox.com wrote:
  Hi all,
 
  Here's the main blocker for adding a matrix multiply operator '@' to
  Python:
  we need to decide what we think its precedence and associativity should
  be.

 Another data point that might be useful:

 Matlab: same-left


 R: tight-left



 I was going to ask this earlier, but I was worried I was missing something
 major.

 Why was tight-left not an option?


 This means that if you don't use parentheses, you get:
a @ b @ c  -  (a @ b) @ c
a * b @ c  -  a * (b @ c)
a @ b * c  -  (a @ b) * c


 In my (very inexperienced) opinion, it seems like the most intuitive option.

Because tight-left doesn't seem to have much to recommend it over
same-left, and all else being equal having fewer levels of precedence
is usually considered a good thing. Unless I'm missing something. If
we do decide that tight-left is best then we could certainly advocate
for it.

I wouldn't read too much into R's choice; they don't actually define a
separate precedence level for matrix multiplication specifically. They
have a single precedence level for all special (user-defined)
operators, and matrix multiplication happens to be one of these.
(Their versions of // and % are also special, but I don't think
anyone would expect // to bind more tightly than / if one were
choosing precedences on a case-by-case basis.)

-n

-- 
Nathaniel J. Smith
Postdoctoral researcher - Informatics - University of Edinburgh
http://vorpus.org
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Alexander Belopolsky
On Sat, Mar 15, 2014 at 2:25 PM, Alexander Belopolsky ndar...@mac.comwrote:

 On Fri, Mar 14, 2014 at 11:41 PM, Nathaniel Smith n...@pobox.com wrote:

 Here's the main blocker for adding a matrix multiply operator '@' to
 Python: we need to decide what we think its precedence and associativity
 should be.


 I am not ready to form my own opinion, but I hope the following will help
 shaping the discussion.


One more question that I think should be answered by the PEP and may
influence the associativity decision is what happens if in an A @ B @ C
expression, each operand has its own type that defines __matmul__ and
__rmatmul__?  For example, A can be an ndarray, B a sympy expression and C
a pyoperator.
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Charles R Harris
On Sat, Mar 15, 2014 at 12:40 PM, Nathaniel Smith n...@pobox.com wrote:

 On Sat, Mar 15, 2014 at 6:33 PM, Joe Kington joferking...@gmail.com
 wrote:
  On Sat, Mar 15, 2014 at 1:28 PM, Nathaniel Smith n...@pobox.com wrote:
 
  On Sat, Mar 15, 2014 at 3:41 AM, Nathaniel Smith n...@pobox.com wrote:
   Hi all,
  
   Here's the main blocker for adding a matrix multiply operator '@' to
   Python:
   we need to decide what we think its precedence and associativity
 should
   be.
 
  Another data point that might be useful:
 
  Matlab: same-left
 
 
  R: tight-left
 
 
 
  I was going to ask this earlier, but I was worried I was missing
 something
  major.
 
  Why was tight-left not an option?
 
 
  This means that if you don't use parentheses, you get:
 a @ b @ c  -  (a @ b) @ c
 a * b @ c  -  a * (b @ c)
 a @ b * c  -  (a @ b) * c
 
 
  In my (very inexperienced) opinion, it seems like the most intuitive
 option.

 Because tight-left doesn't seem to have much to recommend it over
 same-left, and all else being equal having fewer levels of precedence
 is usually considered a good thing. Unless I'm missing something. If
 we do decide that tight-left is best then we could certainly advocate
 for it.

 I wouldn't read too much into R's choice; they don't actually define a
 separate precedence level for matrix multiplication specifically. They
 have a single precedence level for all special (user-defined)
 operators, and matrix multiplication happens to be one of these.
 (Their versions of // and % are also special, but I don't think
 anyone would expect // to bind more tightly than / if one were
 choosing precedences on a case-by-case basis.)


Just to throw something new into the mix

 u@v@w = u@(v@w) -- u@v is a dyadic matrix

 u@v -- is a scalar

It would be nice if u@v@None, or some such, would evaluate as a dyad. Or
else we will still need the concept of row and column 1-D matrices. I still
think v.T should set a flag so that one can distinguish u@v.T (dyad) from
u.T@v (inner product), where 1-D arrays are normally treated as column
vectors.

Chuck
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Charles R Harris
On Sat, Mar 15, 2014 at 1:01 PM, Alexander Belopolsky ndar...@mac.comwrote:


 On Sat, Mar 15, 2014 at 2:25 PM, Alexander Belopolsky ndar...@mac.comwrote:

 On Fri, Mar 14, 2014 at 11:41 PM, Nathaniel Smith n...@pobox.com wrote:

 Here's the main blocker for adding a matrix multiply operator '@' to
 Python: we need to decide what we think its precedence and associativity
 should be.


 I am not ready to form my own opinion, but I hope the following will help
 shaping the discussion.


 One more question that I think should be answered by the PEP and may
 influence the associativity decision is what happens if in an A @ B @ C
 expression, each operand has its own type that defines __matmul__ and
 __rmatmul__?  For example, A can be an ndarray, B a sympy expression and C
 a pyoperator.


My impression is that the pyoperator folks would prefer right associativity
as it corresponds to function composition, which also proceeds right to
left. I don't think the sympy folks have expressed and opinion, except
perhaps that they are more in the sage camp where matrices are symbolic,
and not to be confused with arrays. That is, they don't depend on having
two operators, one for the Hadamard product and another for the matrix
product.

Chuck
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Nathaniel Smith
On 15 Mar 2014 19:02, Charles R Harris charlesr.har...@gmail.com wrote:
 Just to throw something new into the mix

  u@v@w = u@(v@w) -- u@v is a dyadic matrix

  u@v -- is a scalar

 It would be nice if u@v@None, or some such, would evaluate as a dyad. Or
else we will still need the concept of row and column 1-D matrices. I still
think v.T should set a flag so that one can distinguish u@v.T (dyad) from
u.T@v (inner product), where 1-D arrays are normally treated as column
vectors.

This sounds important but I have no idea what any of it means :-) (What's a
dyadic matrix?) Can you elaborate?

-n
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Alexander Belopolsky
On Sat, Mar 15, 2014 at 3:29 PM, Nathaniel Smith n...@pobox.com wrote:

  It would be nice if u@v@None, or some such, would evaluate as a dyad.
 Or else we will still need the concept of row and column 1-D matrices. I
 still think v.T should set a flag so that one can distinguish u@v.T(dyad) 
 from u.T@v(inner product), where 1-D arrays are normally treated as column 
 vectors.

 This sounds important but I have no idea what any of it means :-) (What's
 a dyadic matrix?) Can you elaborate?


I assume dyadic means 2d.

This discussion gave me an idea that is only tangentially relevant to the
discussion at hand.  It looks like numpy operators commonly need to make a
choice whether to treat an Nd array as a unit (atom) or as a list to
broadcast itself over.

APL-derived languages solve this problem by using operator modifiers.
 Applied to our case, given a dot-product operator @, each[@] operator
works on  2d arrays by dotting them pair-wise and returning a 1d array.
 Similarly, eachleft[@] would operate on 2d, 1d operands by broadcasting
itself over the left operand (incidentally reproducing the mat @ vec
behavior) and eachright[@] would treat its left operand atomically and
broadcast over the right operand.

My idea is inspired by Guido's use facade suggestion.  We can define
ndarray.each(axes=(0,)) method that would return a light-weigh proxy object
so that

a each[@] b  is spelled a.each() @ b.each()
a eachleft[@] b is spelled a.each() @ b
a eachright[@] b is spelled a @ b.each()
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Charles R Harris
On Sat, Mar 15, 2014 at 1:29 PM, Nathaniel Smith n...@pobox.com wrote:

 On 15 Mar 2014 19:02, Charles R Harris charlesr.har...@gmail.com
 wrote:
  Just to throw something new into the mix
 
   u@v@w = u@(v@w) -- u@v is a dyadic matrix
 
   u@v -- is a scalar
 
  It would be nice if u@v@None, or some such, would evaluate as a dyad.
 Or else we will still need the concept of row and column 1-D matrices. I
 still think v.T should set a flag so that one can distinguish u@v.T(dyad) 
 from u.T@v(inner product), where 1-D arrays are normally treated as column 
 vectors.

 This sounds important but I have no idea what any of it means :-) (What's
 a dyadic matrix?) Can you elaborate?


Dyadic matrices date back to the beginning of vector calculus and J. W.
Gibbs. These days they are usually written as v*w.T, i.e., the outer
product of two vectors and are a fairly common occurrence in matrix
expressions. For instance, covariance matrices  are defined as E(v * v.T)

Chuck
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Alexander Belopolsky
On Sat, Mar 15, 2014 at 4:00 PM, Charles R Harris charlesr.har...@gmail.com
 wrote:

 These days they are usually written as v*w.T, i.e., the outer product of
 two vectors and are a fairly common occurrence in matrix expressions. For
 instance, covariance matrices  are defined as E(v * v.T)


With the current numpy, we can do

 x = arange(1, 5)
 x[:,None].dot(x[None,:])
array([[ 1,  2,  3,  4],
   [ 2,  4,  6,  8],
   [ 3,  6,  9, 12],
   [ 4,  8, 12, 16]])

I assume once @ becomes available, we will have

 x[:,None] @ x[None,:]
array([[ 1,  2,  3,  4],
   [ 2,  4,  6,  8],
   [ 3,  6,  9, 12],
   [ 4,  8, 12, 16]])
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Charles R Harris
On Sat, Mar 15, 2014 at 2:12 PM, Alexander Belopolsky ndar...@mac.comwrote:


 On Sat, Mar 15, 2014 at 4:00 PM, Charles R Harris 
 charlesr.har...@gmail.com wrote:

 These days they are usually written as v*w.T, i.e., the outer product of
 two vectors and are a fairly common occurrence in matrix expressions. For
 instance, covariance matrices  are defined as E(v * v.T)


 With the current numpy, we can do

  x = arange(1, 5)
  x[:,None].dot(x[None,:])
 array([[ 1,  2,  3,  4],
[ 2,  4,  6,  8],
[ 3,  6,  9, 12],
[ 4,  8, 12, 16]])

 I assume once @ becomes available, we will have

  x[:,None] @ x[None,:]
 array([[ 1,  2,  3,  4],
[ 2,  4,  6,  8],
[ 3,  6,  9, 12],
[ 4,  8, 12, 16]])


Yes, that works. I was thinking more of easy translation of the forms found
in textbooks. Householder reflection, for instance, is usually written as

I - 2 * v * v.T

Where the `v` are unit vectors.

Chuck
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [RFC] should we argue for a matrix power operator, @@?

2014-03-15 Thread Stephan Hoyer
Speaking only for myself (and as someone who has regularly used matrix
powers), I would not expect matrix power as @@ to follow from matrix
multiplication as @. I do agree that matrix power is the only reasonable
use for @@ (given @), but it's still not something I would be confident
enough to know without looking up.

We should keep in mind that each new operator imposes some (small)
cognitive burden on everyone who encounters them for the first time, and,
in this case, this will include a large fraction of all Python users,
whether they do numerical computation or not.

Guido has given us a tremendous gift in the form of @. Let's not insist on
@@, when it is unclear if the burden of figuring out what @@ means it would
be worth using, even for heavily numeric code. I would certainly prefer to
encounter norm(A), inv(A), matrix_power(A, n), fractional_matrix_power(A,
n) and expm(A) rather than their infix equivalents. It will certainly not
be obvious which of these @@ will support for objects from any given
library.

One useful data point might be to consider whether matrix power is
available as an infix operator in other languages commonly used for
numerical work. AFAICT from some quick searches:
MATLAB: Yes
R: No
IDL: No

All of these languages do, of course, implement infix matrix
multiplication, but it is apparently not clear at all whether the matrix
power is useful.

Best,
Stephan




On Sat, Mar 15, 2014 at 9:03 AM, Olivier Delalleau sh...@keba.be wrote:

 2014-03-15 11:18 GMT-04:00 Charles R Harris charlesr.har...@gmail.com:




 On Fri, Mar 14, 2014 at 10:32 PM, Nathaniel Smith n...@pobox.com wrote:

 Hi all,

 Here's the second thread for discussion about Guido's concerns about
 PEP 465. The issue here is that PEP 465 as currently written proposes
 two new operators, @ for matrix multiplication and @@ for matrix power
 (analogous to * and **):
   http://legacy.python.org/dev/peps/pep-0465/

 The main thing we care about of course is @; I pushed for including @@
 because I thought it was nicer to have than not, and I thought the
 analogy between * and ** might make the overall package more appealing
 to Guido's aesthetic sense.

 It turns out I was wrong :-). Guido is -0 on @@, but willing to be
 swayed if we think it's worth the trouble to make a solid case.

 Note that question now is *not*, how will @@ affect the reception of
 @. @ itself is AFAICT a done deal, regardless of what happens with @@.
 For this discussion let's assume @ can be taken for granted, and that
 we can freely choose to either add @@ or not add @@ to the language.
 The question is: which do we think makes Python a better language (for
 us and in general)?

 Some thoughts to start us off:

 Here are the interesting use cases for @@ that I can think of:
 - 'vector @@ 2' gives the squared Euclidean length (because it's the
 same as vector @ vector). Kind of handy.
 - 'matrix @@ n' of course gives the matrix power, which is of marginal
 use but does come in handy sometimes, e.g., when looking at graph
 connectivity.
 - 'matrix @@ -1' provides a very transparent notation for translating
 textbook formulas (with all their inverses) into code. It's a bit
 unhelpful in practice, because (a) usually you should use solve(), and
 (b) 'matrix @@ -1' is actually more characters than 'inv(matrix)'. But
 sometimes transparent notation may be important. (And in some cases,
 like using numba or theano or whatever, 'matrix @@ -1 @ foo' could be
 compiled into a call to solve() anyway.)

 (Did I miss any?)

 In practice it seems to me that the last use case is the one that's
 might matter a lot practice, but then again, it might not -- I'm not
 sure. For example, does anyone who teaches programming with numpy have
 a feeling about whether the existence of '@@ -1' would make a big
 difference to you and your students? (Alan? I know you were worried
 about losing the .I attribute on matrices if switching to ndarrays for
 teaching -- given that ndarray will probably not get a .I attribute,
 how much would the existence of @@ -1 affect you?)

 On a more technical level, Guido is worried about how @@'s precedence
 should work (and this is somewhat related to the other thread about
 @'s precedence and associativity, because he feels that if we end up
 giving @ and * different precedence, then that makes it much less
 clear what to do with @@, and reduces the strength of the */**/@/@@
 analogy). In particular, if we want to argue for @@ then we'll need to
 figure out what expressions like
a @@ b @@ c
 and
a ** b @@ c
 and
a @@ b ** c
 should do.

 A related question is what @@ should do if given an array as its right
 argument. In the current PEP, only integers are accepted, which rules
 out a bunch of the more complicated cases like a @@ b @@ c (at least
 assuming @@ is right-associative, like **, and I can't see why you'd
 want anything else). OTOH, in the brave new gufunc world, it
 technically would make sense to define @@ as being a 

Re: [Numpy-discussion] [RFC] should we argue for a matrix power operator, @@?

2014-03-15 Thread josef . pktd
I think I wouldn't use anything like @@ often enough to remember it's
meaning. I'd rather see english names for anything that is not **very**
common.

I find A@@-1 pretty ugly compared to inv(A)
A@@(-0.5)  might be nice   (do we have matrix_sqrt ?)

Josef


On Sat, Mar 15, 2014 at 5:11 PM, Stephan Hoyer sho...@gmail.com wrote:

 Speaking only for myself (and as someone who has regularly used matrix
 powers), I would not expect matrix power as @@ to follow from matrix
 multiplication as @. I do agree that matrix power is the only reasonable
 use for @@ (given @), but it's still not something I would be confident
 enough to know without looking up.

 We should keep in mind that each new operator imposes some (small)
 cognitive burden on everyone who encounters them for the first time, and,
 in this case, this will include a large fraction of all Python users,
 whether they do numerical computation or not.

 Guido has given us a tremendous gift in the form of @. Let's not insist on
 @@, when it is unclear if the burden of figuring out what @@ means it would
 be worth using, even for heavily numeric code. I would certainly prefer to
 encounter norm(A), inv(A), matrix_power(A, n), fractional_matrix_power(A,
 n) and expm(A) rather than their infix equivalents. It will certainly not
 be obvious which of these @@ will support for objects from any given
 library.

 One useful data point might be to consider whether matrix power is
 available as an infix operator in other languages commonly used for
 numerical work. AFAICT from some quick searches:
 MATLAB: Yes
 R: No
 IDL: No

 All of these languages do, of course, implement infix matrix
 multiplication, but it is apparently not clear at all whether the matrix
 power is useful.

 Best,
 Stephan




 On Sat, Mar 15, 2014 at 9:03 AM, Olivier Delalleau sh...@keba.be wrote:

 2014-03-15 11:18 GMT-04:00 Charles R Harris charlesr.har...@gmail.com:




 On Fri, Mar 14, 2014 at 10:32 PM, Nathaniel Smith n...@pobox.com wrote:

 Hi all,

 Here's the second thread for discussion about Guido's concerns about
 PEP 465. The issue here is that PEP 465 as currently written proposes
 two new operators, @ for matrix multiplication and @@ for matrix power
 (analogous to * and **):
   http://legacy.python.org/dev/peps/pep-0465/

 The main thing we care about of course is @; I pushed for including @@
 because I thought it was nicer to have than not, and I thought the
 analogy between * and ** might make the overall package more appealing
 to Guido's aesthetic sense.

 It turns out I was wrong :-). Guido is -0 on @@, but willing to be
 swayed if we think it's worth the trouble to make a solid case.

 Note that question now is *not*, how will @@ affect the reception of
 @. @ itself is AFAICT a done deal, regardless of what happens with @@.
 For this discussion let's assume @ can be taken for granted, and that
 we can freely choose to either add @@ or not add @@ to the language.
 The question is: which do we think makes Python a better language (for
 us and in general)?

 Some thoughts to start us off:

 Here are the interesting use cases for @@ that I can think of:
 - 'vector @@ 2' gives the squared Euclidean length (because it's the
 same as vector @ vector). Kind of handy.
 - 'matrix @@ n' of course gives the matrix power, which is of marginal
 use but does come in handy sometimes, e.g., when looking at graph
 connectivity.
 - 'matrix @@ -1' provides a very transparent notation for translating
 textbook formulas (with all their inverses) into code. It's a bit
 unhelpful in practice, because (a) usually you should use solve(), and
 (b) 'matrix @@ -1' is actually more characters than 'inv(matrix)'. But
 sometimes transparent notation may be important. (And in some cases,
 like using numba or theano or whatever, 'matrix @@ -1 @ foo' could be
 compiled into a call to solve() anyway.)

 (Did I miss any?)

 In practice it seems to me that the last use case is the one that's
 might matter a lot practice, but then again, it might not -- I'm not
 sure. For example, does anyone who teaches programming with numpy have
 a feeling about whether the existence of '@@ -1' would make a big
 difference to you and your students? (Alan? I know you were worried
 about losing the .I attribute on matrices if switching to ndarrays for
 teaching -- given that ndarray will probably not get a .I attribute,
 how much would the existence of @@ -1 affect you?)

 On a more technical level, Guido is worried about how @@'s precedence
 should work (and this is somewhat related to the other thread about
 @'s precedence and associativity, because he feels that if we end up
 giving @ and * different precedence, then that makes it much less
 clear what to do with @@, and reduces the strength of the */**/@/@@
 analogy). In particular, if we want to argue for @@ then we'll need to
 figure out what expressions like
a @@ b @@ c
 and
a ** b @@ c
 and
a @@ b ** c
 should do.

 A related question is what @@ should do 

Re: [Numpy-discussion] [RFC] should we argue for a matrix power operator, @@?

2014-03-15 Thread Warren Weckesser
On Sat, Mar 15, 2014 at 8:38 PM, josef.p...@gmail.com wrote:

 I think I wouldn't use anything like @@ often enough to remember it's
 meaning. I'd rather see english names for anything that is not **very**
 common.

 I find A@@-1 pretty ugly compared to inv(A)
 A@@(-0.5)  might be nice   (do we have matrix_sqrt ?)



scipy.linalg.sqrtm:
http://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.sqrtm.html

Warren



 Josef



 On Sat, Mar 15, 2014 at 5:11 PM, Stephan Hoyer sho...@gmail.com wrote:

 Speaking only for myself (and as someone who has regularly used matrix
 powers), I would not expect matrix power as @@ to follow from matrix
 multiplication as @. I do agree that matrix power is the only reasonable
 use for @@ (given @), but it's still not something I would be confident
 enough to know without looking up.

 We should keep in mind that each new operator imposes some (small)
 cognitive burden on everyone who encounters them for the first time, and,
 in this case, this will include a large fraction of all Python users,
 whether they do numerical computation or not.

 Guido has given us a tremendous gift in the form of @. Let's not insist
 on @@, when it is unclear if the burden of figuring out what @@ means it
 would be worth using, even for heavily numeric code. I would certainly
 prefer to encounter norm(A), inv(A), matrix_power(A, n),
 fractional_matrix_power(A, n) and expm(A) rather than their infix
 equivalents. It will certainly not be obvious which of these @@ will
 support for objects from any given library.

 One useful data point might be to consider whether matrix power is
 available as an infix operator in other languages commonly used for
 numerical work. AFAICT from some quick searches:
 MATLAB: Yes
 R: No
 IDL: No

 All of these languages do, of course, implement infix matrix
 multiplication, but it is apparently not clear at all whether the matrix
 power is useful.

 Best,
 Stephan




 On Sat, Mar 15, 2014 at 9:03 AM, Olivier Delalleau sh...@keba.be wrote:

 2014-03-15 11:18 GMT-04:00 Charles R Harris charlesr.har...@gmail.com:




 On Fri, Mar 14, 2014 at 10:32 PM, Nathaniel Smith n...@pobox.comwrote:

 Hi all,

 Here's the second thread for discussion about Guido's concerns about
 PEP 465. The issue here is that PEP 465 as currently written proposes
 two new operators, @ for matrix multiplication and @@ for matrix power
 (analogous to * and **):
   http://legacy.python.org/dev/peps/pep-0465/

 The main thing we care about of course is @; I pushed for including @@
 because I thought it was nicer to have than not, and I thought the
 analogy between * and ** might make the overall package more appealing
 to Guido's aesthetic sense.

 It turns out I was wrong :-). Guido is -0 on @@, but willing to be
 swayed if we think it's worth the trouble to make a solid case.

 Note that question now is *not*, how will @@ affect the reception of
 @. @ itself is AFAICT a done deal, regardless of what happens with @@.
 For this discussion let's assume @ can be taken for granted, and that
 we can freely choose to either add @@ or not add @@ to the language.
 The question is: which do we think makes Python a better language (for
 us and in general)?

 Some thoughts to start us off:

 Here are the interesting use cases for @@ that I can think of:
 - 'vector @@ 2' gives the squared Euclidean length (because it's the
 same as vector @ vector). Kind of handy.
 - 'matrix @@ n' of course gives the matrix power, which is of marginal
 use but does come in handy sometimes, e.g., when looking at graph
 connectivity.
 - 'matrix @@ -1' provides a very transparent notation for translating
 textbook formulas (with all their inverses) into code. It's a bit
 unhelpful in practice, because (a) usually you should use solve(), and
 (b) 'matrix @@ -1' is actually more characters than 'inv(matrix)'. But
 sometimes transparent notation may be important. (And in some cases,
 like using numba or theano or whatever, 'matrix @@ -1 @ foo' could be
 compiled into a call to solve() anyway.)

 (Did I miss any?)

 In practice it seems to me that the last use case is the one that's
 might matter a lot practice, but then again, it might not -- I'm not
 sure. For example, does anyone who teaches programming with numpy have
 a feeling about whether the existence of '@@ -1' would make a big
 difference to you and your students? (Alan? I know you were worried
 about losing the .I attribute on matrices if switching to ndarrays for
 teaching -- given that ndarray will probably not get a .I attribute,
 how much would the existence of @@ -1 affect you?)

 On a more technical level, Guido is worried about how @@'s precedence
 should work (and this is somewhat related to the other thread about
 @'s precedence and associativity, because he feels that if we end up
 giving @ and * different precedence, then that makes it much less
 clear what to do with @@, and reduces the strength of the */**/@/@@
 analogy). In particular, if we want to 

Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread josef . pktd
On Fri, Mar 14, 2014 at 11:41 PM, Nathaniel Smith n...@pobox.com wrote:

 Hi all,

 Here's the main blocker for adding a matrix multiply operator '@' to
 Python: we need to decide what we think its precedence and associativity
 should be. I'll explain what that means so we're on the same page, and what
 the choices are, and then we can all argue about it. But even better would
 be if we could get some data to guide our decision, and this would be a lot
 easier if some of you all can help; I'll suggest some ways you might be
 able to do that.

 So! Precedence and left- versus right-associativity. If you already know
 what these are you can skim down until you see CAPITAL LETTERS.

 We all know what precedence is. Code like this:
   a + b * c
 gets evaluated as:
   a + (b * c)
 because * has higher precedence than +. It binds more tightly, as they
 say. Python's complete precedence able is here:
   http://docs.python.org/3/reference/expressions.html#operator-precedence

 Associativity, in the parsing sense, is less well known, though it's just
 as important. It's about deciding how to evaluate code like this:
   a * b * c
 Do we use
   a * (b * c)# * is right associative
 or
   (a * b) * c# * is left associative
 ? Here all the operators have the same precedence (because, uh... they're
 the same operator), so precedence doesn't help. And mostly we can ignore
 this in day-to-day life, because both versions give the same answer, so who
 cares. But a programming language has to pick one (consider what happens if
 one of those objects has a non-default __mul__ implementation). And of
 course it matters a lot for non-associative operations like
   a - b - c
 or
   a / b / c
 So when figuring out order of evaluations, what you do first is check the
 precedence, and then if you have multiple operators next to each other with
 the same precedence, you check their associativity. Notice that this means
 that if you have different operators that share the same precedence level
 (like + and -, or * and /), then they have to all have the same
 associativity. All else being equal, it's generally considered nice to have
 fewer precedence levels, because these have to be memorized by users.

 Right now in Python, every precedence level is left-associative, except
 for '**'. If you write these formulas without any parentheses, then what
 the interpreter will actually execute is:
   (a * b) * c
   (a - b) - c
   (a / b) / c
 but
   a ** (b ** c)

 Okay, that's the background. Here's the question. We need to decide on
 precedence and associativity for '@'. In particular, there are three
 different options that are interesting:

 OPTION 1 FOR @:
 Precedence: same as *
 Associativity: left
 My shorthand name for it: same-left (yes, very creative)

 This means that if you don't use parentheses, you get:
a @ b @ c  -  (a @ b) @ c
a * b @ c  -  (a * b) @ c
a @ b * c  -  (a @ b) * c

 OPTION 2 FOR @:
 Precedence: more-weakly-binding than *
 Associativity: right
 My shorthand name for it: weak-right

 This means that if you don't use parentheses, you get:
a @ b @ c  -  a @ (b @ c)
a * b @ c  -  (a * b) @ c
a @ b * c  -  a @ (b * c)

 OPTION 3 FOR @:
 Precedence: more-tightly-binding than *
 Associativity: right
 My shorthand name for it: tight-right

 This means that if you don't use parentheses, you get:
a @ b @ c  -  a @ (b @ c)
a * b @ c  -  a * (b @ c)
a @ b * c  -  (a @ b) * c

 We need to pick which of which options we think is best, based on whatever
 reasons we can think of, ideally more than hmm, weak-right gives me warm
 fuzzy feelings ;-). (In principle the other 2 possible options are
 tight-left and weak-left, but there doesn't seem to be any argument in
 favor of either, so we'll leave them out of the discussion.)

 Some things to consider:

 * and @ are actually not associative (in the math sense) with respect to
 each other, i.e., (a * b) @ c and a * (b @ c) in general give different
 results when 'a' is not a scalar. So considering the two expressions 'a * b
 @ c' and 'a @ b * c', we can see that each of these three options gives
 produces different results in some cases.

 Same-left is the easiest to explain and remember, because it's just, @
 acts like * and /. So we already have to know the rule in order to
 understand other non-associative expressions like a / b / c or a - b - c,
 and it'd be nice if the same rule applied to things like a * b @ c so we
 only had to memorize *one* rule. (Of course there's ** which uses the
 opposite rule, but I guess everyone internalized that one in secondary
 school; that's not true for * versus @.) This is definitely the default we
 should choose unless we have a good reason to do otherwise.

 BUT: there might indeed be a good reason to do otherwise, which is the
 whole reason this has come up. Consider:
 Mat1 @ Mat2 @ vec
 Obviously this will execute much more quickly if we do
 Mat1 @ (Mat2 @ vec)
 because that results in 

Re: [Numpy-discussion] [RFC] should we argue for a matrix power operator, @@?

2014-03-15 Thread josef . pktd
On Sat, Mar 15, 2014 at 8:47 PM, Warren Weckesser 
warren.weckes...@gmail.com wrote:


 On Sat, Mar 15, 2014 at 8:38 PM, josef.p...@gmail.com wrote:

 I think I wouldn't use anything like @@ often enough to remember it's
 meaning. I'd rather see english names for anything that is not **very**
 common.

 I find A@@-1 pretty ugly compared to inv(A)
 A@@(-0.5)  might be nice   (do we have matrix_sqrt ?)



 scipy.linalg.sqrtm:
 http://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.sqrtm.html


maybe a good example: I could never figured that one out

M = sqrtm(A)

A = M @ M

but what we use in stats is

A = R.T @ R
(eigenvectors dot diag(sqrt of eigenvalues)

which sqrt is A@@(0.5) ?

Josef





 Warren



 Josef



 On Sat, Mar 15, 2014 at 5:11 PM, Stephan Hoyer sho...@gmail.com wrote:

 Speaking only for myself (and as someone who has regularly used matrix
 powers), I would not expect matrix power as @@ to follow from matrix
 multiplication as @. I do agree that matrix power is the only reasonable
 use for @@ (given @), but it's still not something I would be confident
 enough to know without looking up.

 We should keep in mind that each new operator imposes some (small)
 cognitive burden on everyone who encounters them for the first time, and,
 in this case, this will include a large fraction of all Python users,
 whether they do numerical computation or not.

 Guido has given us a tremendous gift in the form of @. Let's not insist
 on @@, when it is unclear if the burden of figuring out what @@ means it
 would be worth using, even for heavily numeric code. I would certainly
 prefer to encounter norm(A), inv(A), matrix_power(A, n),
 fractional_matrix_power(A, n) and expm(A) rather than their infix
 equivalents. It will certainly not be obvious which of these @@ will
 support for objects from any given library.

 One useful data point might be to consider whether matrix power is
 available as an infix operator in other languages commonly used for
 numerical work. AFAICT from some quick searches:
 MATLAB: Yes
 R: No
 IDL: No

 All of these languages do, of course, implement infix matrix
 multiplication, but it is apparently not clear at all whether the matrix
 power is useful.

 Best,
 Stephan




 On Sat, Mar 15, 2014 at 9:03 AM, Olivier Delalleau sh...@keba.bewrote:

 2014-03-15 11:18 GMT-04:00 Charles R Harris charlesr.har...@gmail.com
 :




 On Fri, Mar 14, 2014 at 10:32 PM, Nathaniel Smith n...@pobox.comwrote:

 Hi all,

 Here's the second thread for discussion about Guido's concerns about
 PEP 465. The issue here is that PEP 465 as currently written proposes
 two new operators, @ for matrix multiplication and @@ for matrix power
 (analogous to * and **):
   http://legacy.python.org/dev/peps/pep-0465/

 The main thing we care about of course is @; I pushed for including @@
 because I thought it was nicer to have than not, and I thought the
 analogy between * and ** might make the overall package more appealing
 to Guido's aesthetic sense.

 It turns out I was wrong :-). Guido is -0 on @@, but willing to be
 swayed if we think it's worth the trouble to make a solid case.

 Note that question now is *not*, how will @@ affect the reception of
 @. @ itself is AFAICT a done deal, regardless of what happens with @@.
 For this discussion let's assume @ can be taken for granted, and that
 we can freely choose to either add @@ or not add @@ to the language.
 The question is: which do we think makes Python a better language (for
 us and in general)?

 Some thoughts to start us off:

 Here are the interesting use cases for @@ that I can think of:
 - 'vector @@ 2' gives the squared Euclidean length (because it's the
 same as vector @ vector). Kind of handy.
 - 'matrix @@ n' of course gives the matrix power, which is of marginal
 use but does come in handy sometimes, e.g., when looking at graph
 connectivity.
 - 'matrix @@ -1' provides a very transparent notation for translating
 textbook formulas (with all their inverses) into code. It's a bit
 unhelpful in practice, because (a) usually you should use solve(), and
 (b) 'matrix @@ -1' is actually more characters than 'inv(matrix)'. But
 sometimes transparent notation may be important. (And in some cases,
 like using numba or theano or whatever, 'matrix @@ -1 @ foo' could be
 compiled into a call to solve() anyway.)

 (Did I miss any?)

 In practice it seems to me that the last use case is the one that's
 might matter a lot practice, but then again, it might not -- I'm not
 sure. For example, does anyone who teaches programming with numpy have
 a feeling about whether the existence of '@@ -1' would make a big
 difference to you and your students? (Alan? I know you were worried
 about losing the .I attribute on matrices if switching to ndarrays for
 teaching -- given that ndarray will probably not get a .I attribute,
 how much would the existence of @@ -1 affect you?)

 On a more technical level, Guido is worried about how @@'s precedence
 should work 

Re: [Numpy-discussion] [RFC] should we argue for a matrix power operator, @@?

2014-03-15 Thread Nathaniel Smith
On Sat, Mar 15, 2014 at 1:13 PM, Alan G Isaac alan.is...@gmail.com wrote:
 On 3/15/2014 12:32 AM, Nathaniel Smith wrote:
   I know you were worried
 about losing the .I attribute on matrices if switching to ndarrays for
 teaching -- given that ndarray will probably not get a .I attribute,
 how much would the existence of @@ -1 affect you?

 Not much. Positive integer powers would be useful
 (for illustrating e.g. graph theory and difference equations),
 but not enough to delay the PEP.

So to be clear, even if numpy.matrix is going away, and even if
ndarray isn't getting a .I attribute, then you're just as happy
typing/teaching inv(X) as X @@ -1?

 I think NumPy should take the money and run.
 Getting `@` is great.  Let's get experience with
 it before deciding whether it's worth asking for `@@`.

 Questions for `@@`:
 - would it just be `matrix_power`, with all the restrictions?
 - or would `a(10,2,2)@@-1` return an array of matrix inverses?
 - etc

The version in the PEP does do gufunc-style broadcasting for 2d
arrays, yes. So will np.linalg.matrix_power as soon as someone bothers
to send a patch ;-)

 In the end, I'd like to see a functional implementation before
 deciding on `@@`, but I would not like to see `@` delayed at all.

Oh, well, not much is going to affect `@`'s timing, unless we're
*dreadfully* slow. Py 3.5 isn't even scheduled yet b/c 3.4 isn't out,
and IIUC Python's standard release cycle is 18 months. So we've got a
year+ before feature freeze, regardless.

-n

-- 
Nathaniel J. Smith
Postdoctoral researcher - Informatics - University of Edinburgh
http://vorpus.org
___
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion


Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Charles R Harris
On Sat, Mar 15, 2014 at 7:20 PM, josef.p...@gmail.com wrote:




 On Fri, Mar 14, 2014 at 11:41 PM, Nathaniel Smith n...@pobox.com wrote:

 Hi all,

 Here's the main blocker for adding a matrix multiply operator '@' to
 Python: we need to decide what we think its precedence and associativity
 should be. I'll explain what that means so we're on the same page, and what
 the choices are, and then we can all argue about it. But even better would
 be if we could get some data to guide our decision, and this would be a lot
 easier if some of you all can help; I'll suggest some ways you might be
 able to do that.

 So! Precedence and left- versus right-associativity. If you already know
 what these are you can skim down until you see CAPITAL LETTERS.

 We all know what precedence is. Code like this:
   a + b * c
 gets evaluated as:
   a + (b * c)
 because * has higher precedence than +. It binds more tightly, as they
 say. Python's complete precedence able is here:
   http://docs.python.org/3/reference/expressions.html#operator-precedence

 Associativity, in the parsing sense, is less well known, though it's just
 as important. It's about deciding how to evaluate code like this:
   a * b * c
 Do we use
   a * (b * c)# * is right associative
 or
   (a * b) * c# * is left associative
 ? Here all the operators have the same precedence (because, uh... they're
 the same operator), so precedence doesn't help. And mostly we can ignore
 this in day-to-day life, because both versions give the same answer, so who
 cares. But a programming language has to pick one (consider what happens if
 one of those objects has a non-default __mul__ implementation). And of
 course it matters a lot for non-associative operations like
   a - b - c
 or
   a / b / c
 So when figuring out order of evaluations, what you do first is check the
 precedence, and then if you have multiple operators next to each other with
 the same precedence, you check their associativity. Notice that this means
 that if you have different operators that share the same precedence level
 (like + and -, or * and /), then they have to all have the same
 associativity. All else being equal, it's generally considered nice to have
 fewer precedence levels, because these have to be memorized by users.

 Right now in Python, every precedence level is left-associative, except
 for '**'. If you write these formulas without any parentheses, then what
 the interpreter will actually execute is:
   (a * b) * c
   (a - b) - c
   (a / b) / c
 but
   a ** (b ** c)

 Okay, that's the background. Here's the question. We need to decide on
 precedence and associativity for '@'. In particular, there are three
 different options that are interesting:

 OPTION 1 FOR @:
 Precedence: same as *
 Associativity: left
 My shorthand name for it: same-left (yes, very creative)

 This means that if you don't use parentheses, you get:
a @ b @ c  -  (a @ b) @ c
a * b @ c  -  (a * b) @ c
a @ b * c  -  (a @ b) * c

 OPTION 2 FOR @:
 Precedence: more-weakly-binding than *
 Associativity: right
 My shorthand name for it: weak-right

 This means that if you don't use parentheses, you get:
a @ b @ c  -  a @ (b @ c)
a * b @ c  -  (a * b) @ c
a @ b * c  -  a @ (b * c)

 OPTION 3 FOR @:
 Precedence: more-tightly-binding than *
 Associativity: right
 My shorthand name for it: tight-right

 This means that if you don't use parentheses, you get:
a @ b @ c  -  a @ (b @ c)
a * b @ c  -  a * (b @ c)
a @ b * c  -  (a @ b) * c

 We need to pick which of which options we think is best, based on
 whatever reasons we can think of, ideally more than hmm, weak-right gives
 me warm fuzzy feelings ;-). (In principle the other 2 possible options are
 tight-left and weak-left, but there doesn't seem to be any argument in
 favor of either, so we'll leave them out of the discussion.)

 Some things to consider:

 * and @ are actually not associative (in the math sense) with respect to
 each other, i.e., (a * b) @ c and a * (b @ c) in general give different
 results when 'a' is not a scalar. So considering the two expressions 'a * b
 @ c' and 'a @ b * c', we can see that each of these three options gives
 produces different results in some cases.

 Same-left is the easiest to explain and remember, because it's just, @
 acts like * and /. So we already have to know the rule in order to
 understand other non-associative expressions like a / b / c or a - b - c,
 and it'd be nice if the same rule applied to things like a * b @ c so we
 only had to memorize *one* rule. (Of course there's ** which uses the
 opposite rule, but I guess everyone internalized that one in secondary
 school; that's not true for * versus @.) This is definitely the default we
 should choose unless we have a good reason to do otherwise.

 BUT: there might indeed be a good reason to do otherwise, which is the
 whole reason this has come up. Consider:
 Mat1 @ Mat2 @ vec
 Obviously this will execute much more 

Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread josef . pktd
On Sat, Mar 15, 2014 at 11:30 PM, Charles R Harris 
charlesr.har...@gmail.com wrote:




 On Sat, Mar 15, 2014 at 7:20 PM, josef.p...@gmail.com wrote:




 On Fri, Mar 14, 2014 at 11:41 PM, Nathaniel Smith n...@pobox.com wrote:

 Hi all,

 Here's the main blocker for adding a matrix multiply operator '@' to
 Python: we need to decide what we think its precedence and associativity
 should be. I'll explain what that means so we're on the same page, and what
 the choices are, and then we can all argue about it. But even better would
 be if we could get some data to guide our decision, and this would be a lot
 easier if some of you all can help; I'll suggest some ways you might be
 able to do that.

 So! Precedence and left- versus right-associativity. If you already know
 what these are you can skim down until you see CAPITAL LETTERS.

 We all know what precedence is. Code like this:
   a + b * c
 gets evaluated as:
   a + (b * c)
 because * has higher precedence than +. It binds more tightly, as they
 say. Python's complete precedence able is here:

 http://docs.python.org/3/reference/expressions.html#operator-precedence

 Associativity, in the parsing sense, is less well known, though it's
 just as important. It's about deciding how to evaluate code like this:
   a * b * c
 Do we use
   a * (b * c)# * is right associative
 or
   (a * b) * c# * is left associative
 ? Here all the operators have the same precedence (because, uh...
 they're the same operator), so precedence doesn't help. And mostly we can
 ignore this in day-to-day life, because both versions give the same answer,
 so who cares. But a programming language has to pick one (consider what
 happens if one of those objects has a non-default __mul__ implementation).
 And of course it matters a lot for non-associative operations like
   a - b - c
 or
   a / b / c
 So when figuring out order of evaluations, what you do first is check
 the precedence, and then if you have multiple operators next to each other
 with the same precedence, you check their associativity. Notice that this
 means that if you have different operators that share the same precedence
 level (like + and -, or * and /), then they have to all have the same
 associativity. All else being equal, it's generally considered nice to have
 fewer precedence levels, because these have to be memorized by users.

 Right now in Python, every precedence level is left-associative, except
 for '**'. If you write these formulas without any parentheses, then what
 the interpreter will actually execute is:
   (a * b) * c
   (a - b) - c
   (a / b) / c
 but
   a ** (b ** c)

 Okay, that's the background. Here's the question. We need to decide on
 precedence and associativity for '@'. In particular, there are three
 different options that are interesting:

 OPTION 1 FOR @:
 Precedence: same as *
 Associativity: left
 My shorthand name for it: same-left (yes, very creative)

 This means that if you don't use parentheses, you get:
a @ b @ c  -  (a @ b) @ c
a * b @ c  -  (a * b) @ c
a @ b * c  -  (a @ b) * c

 OPTION 2 FOR @:
 Precedence: more-weakly-binding than *
 Associativity: right
 My shorthand name for it: weak-right

 This means that if you don't use parentheses, you get:
a @ b @ c  -  a @ (b @ c)
a * b @ c  -  (a * b) @ c
a @ b * c  -  a @ (b * c)

 OPTION 3 FOR @:
 Precedence: more-tightly-binding than *
 Associativity: right
 My shorthand name for it: tight-right

 This means that if you don't use parentheses, you get:
a @ b @ c  -  a @ (b @ c)
a * b @ c  -  a * (b @ c)
a @ b * c  -  (a @ b) * c

 We need to pick which of which options we think is best, based on
 whatever reasons we can think of, ideally more than hmm, weak-right gives
 me warm fuzzy feelings ;-). (In principle the other 2 possible options are
 tight-left and weak-left, but there doesn't seem to be any argument in
 favor of either, so we'll leave them out of the discussion.)

 Some things to consider:

 * and @ are actually not associative (in the math sense) with respect to
 each other, i.e., (a * b) @ c and a * (b @ c) in general give different
 results when 'a' is not a scalar. So considering the two expressions 'a * b
 @ c' and 'a @ b * c', we can see that each of these three options gives
 produces different results in some cases.

 Same-left is the easiest to explain and remember, because it's just,
 @ acts like * and /. So we already have to know the rule in order to
 understand other non-associative expressions like a / b / c or a - b - c,
 and it'd be nice if the same rule applied to things like a * b @ c so we
 only had to memorize *one* rule. (Of course there's ** which uses the
 opposite rule, but I guess everyone internalized that one in secondary
 school; that's not true for * versus @.) This is definitely the default we
 should choose unless we have a good reason to do otherwise.

 BUT: there might indeed be a good reason to do otherwise, which is the
 whole reason this 

Re: [Numpy-discussion] [help needed] associativity and precedence of '@'

2014-03-15 Thread Charles R Harris
On Sat, Mar 15, 2014 at 10:53 PM, josef.p...@gmail.com wrote:




 On Sat, Mar 15, 2014 at 11:30 PM, Charles R Harris 
 charlesr.har...@gmail.com wrote:




 On Sat, Mar 15, 2014 at 7:20 PM, josef.p...@gmail.com wrote:




 On Fri, Mar 14, 2014 at 11:41 PM, Nathaniel Smith n...@pobox.com wrote:

 Hi all,

 Here's the main blocker for adding a matrix multiply operator '@' to
 Python: we need to decide what we think its precedence and associativity
 should be. I'll explain what that means so we're on the same page, and what
 the choices are, and then we can all argue about it. But even better would
 be if we could get some data to guide our decision, and this would be a lot
 easier if some of you all can help; I'll suggest some ways you might be
 able to do that.

 So! Precedence and left- versus right-associativity. If you already
 know what these are you can skim down until you see CAPITAL LETTERS.

 We all know what precedence is. Code like this:
   a + b * c
 gets evaluated as:
   a + (b * c)
 because * has higher precedence than +. It binds more tightly, as
 they say. Python's complete precedence able is here:

 http://docs.python.org/3/reference/expressions.html#operator-precedence

 Associativity, in the parsing sense, is less well known, though it's
 just as important. It's about deciding how to evaluate code like this:
   a * b * c
 Do we use
   a * (b * c)# * is right associative
 or
   (a * b) * c# * is left associative
 ? Here all the operators have the same precedence (because, uh...
 they're the same operator), so precedence doesn't help. And mostly we can
 ignore this in day-to-day life, because both versions give the same answer,
 so who cares. But a programming language has to pick one (consider what
 happens if one of those objects has a non-default __mul__ implementation).
 And of course it matters a lot for non-associative operations like
   a - b - c
 or
   a / b / c
 So when figuring out order of evaluations, what you do first is check
 the precedence, and then if you have multiple operators next to each other
 with the same precedence, you check their associativity. Notice that this
 means that if you have different operators that share the same precedence
 level (like + and -, or * and /), then they have to all have the same
 associativity. All else being equal, it's generally considered nice to have
 fewer precedence levels, because these have to be memorized by users.

 Right now in Python, every precedence level is left-associative, except
 for '**'. If you write these formulas without any parentheses, then what
 the interpreter will actually execute is:
   (a * b) * c
   (a - b) - c
   (a / b) / c
 but
   a ** (b ** c)

 Okay, that's the background. Here's the question. We need to decide on
 precedence and associativity for '@'. In particular, there are three
 different options that are interesting:

 OPTION 1 FOR @:
 Precedence: same as *
 Associativity: left
 My shorthand name for it: same-left (yes, very creative)

 This means that if you don't use parentheses, you get:
a @ b @ c  -  (a @ b) @ c
a * b @ c  -  (a * b) @ c
a @ b * c  -  (a @ b) * c

 OPTION 2 FOR @:
 Precedence: more-weakly-binding than *
 Associativity: right
 My shorthand name for it: weak-right

 This means that if you don't use parentheses, you get:
a @ b @ c  -  a @ (b @ c)
a * b @ c  -  (a * b) @ c
a @ b * c  -  a @ (b * c)

 OPTION 3 FOR @:
 Precedence: more-tightly-binding than *
 Associativity: right
 My shorthand name for it: tight-right

 This means that if you don't use parentheses, you get:
a @ b @ c  -  a @ (b @ c)
a * b @ c  -  a * (b @ c)
a @ b * c  -  (a @ b) * c

 We need to pick which of which options we think is best, based on
 whatever reasons we can think of, ideally more than hmm, weak-right gives
 me warm fuzzy feelings ;-). (In principle the other 2 possible options are
 tight-left and weak-left, but there doesn't seem to be any argument in
 favor of either, so we'll leave them out of the discussion.)

 Some things to consider:

 * and @ are actually not associative (in the math sense) with respect
 to each other, i.e., (a * b) @ c and a * (b @ c) in general give different
 results when 'a' is not a scalar. So considering the two expressions 'a * b
 @ c' and 'a @ b * c', we can see that each of these three options gives
 produces different results in some cases.

 Same-left is the easiest to explain and remember, because it's just,
 @ acts like * and /. So we already have to know the rule in order to
 understand other non-associative expressions like a / b / c or a - b - c,
 and it'd be nice if the same rule applied to things like a * b @ c so we
 only had to memorize *one* rule. (Of course there's ** which uses the
 opposite rule, but I guess everyone internalized that one in secondary
 school; that's not true for * versus @.) This is definitely the default we
 should choose unless we have a good reason to do otherwise.

 BUT: there might