Since Stephen was unable to post this directly, he asked me to do so for him -- Perry -----Original Message----- From: Stephen Walton [mailto:stephen.walton@csun.edu] Sent: Thursday, November 21, 2002 2:02 PM To: scipy-user@scipy.net Subject: Vector orientation (pedantry?) This is probably a historical thing but I had to ask. MATLAB distinguishes between row and column vectors, so that the inner (dot) and outer products are a simple matter of switching the order of multiplication. Numeric forces one to use outerproduct(); matrixmultiply() always returns the inner product of two vectors whether they are row, column, or a mixture. MATLAB is mathematically correct, in my opinion. How much pain would it cause for matrixmultiply() to return the inner product for a row times a column vector and the outer product for a column times a row and get rid of outerproduct() altogether? Along the same lines, shouldn't transpose() applied to a row vector yield a column vector and vice versa? Don't shout at me---I'm just asking :-) -- Stephen Walton, Professor, Dept. of Physics & Astronomy, Cal State Northridge stephen.walton@csun.edu
"Perry Greenfield" <perry@stsci.edu> writes:
Since Stephen was unable to post this directly, he asked me to do so for him -- Perry
-----Original Message----- From: Stephen Walton [mailto:stephen.walton@csun.edu] Sent: Thursday, November 21, 2002 2:02 PM To: scipy-user@scipy.net Subject: Vector orientation (pedantry?)
This is probably a historical thing but I had to ask. MATLAB distinguishes between row and column vectors, so that the inner (dot) and outer products are a simple matter of switching the order of multiplication. Numeric forces one to use outerproduct(); matrixmultiply() always returns the inner product of two vectors whether they are row, column, or a mixture.
OK, either I completely misunderstand you (in which case I apologize, I'm a bit tired) or maybe you are just mistaken in your assumptions : (using Numeric 22)
from Numeric import * # col. vec # row vec. dot([[1],[2],[3]], [[1,2,3]]) array([[1, 2, 3], [2, 4, 6], [3, 6, 9]]) matrixmultiply([[1],[2],[3]], [[1,2,3]]) array([[1, 2, 3], [2, 4, 6], [3, 6, 9]])
Well, note that a row and column vector is nothing more than a 1xN or a Nx1 array (as opposed to a what I'd call a 'flat' N-array). That matlab only has matrices and not arrays of different array-rank is more of a bug than a feature. However, I also felt that doing Linear Algebra in Numeric is often quite awkward, so I wrote a matrix class for that is much more functional for that purpose (and than Matrix.py in Numeric), IMHO. I'm going to release it as open source soon, but if you're interested I could send you the code now. cheers, alex
I think we're still blacklisted so the list won't see this. On Fri, 2002-11-22 at 14:11, Alexander Schmolck wrote:
OK, either I completely misunderstand you (in which case I apologize, I'm a bit tired) or maybe you are just mistaken in your assumptions :
(using Numeric 22)
from Numeric import * # col. vec # row vec. dot([[1],[2],[3]], [[1,2,3]]) array([[1, 2, 3], [2, 4, 6], [3, 6, 9]]) matrixmultiply([[1],[2],[3]], [[1,2,3]]) array([[1, 2, 3], [2, 4, 6], [3, 6, 9]])
OK, I see what you did. What I had tried in my naivete' was:
from Numeric import * dot([1,2,3],[1,2,3]) 14
You also wrote:
Well, note that a row and column vector is nothing more than a 1xN or Nx1 array (as opposed to a what I'd call a 'flat' N-array).
So [1,2,3] denotes a 'flat' 3-array to Numeric, while [[1,2,3]] denotes 1-by-3 array? Not sure I understand the distinction. I agree that SciPy is awkward for linear algebra, but it's mainly syntax in my case. <HERESY> I find typing 'x=[1,2,3;4,5,6;7,8,9]' much more straightforward than 'x=array([[1,2,3],[4,5,6],[7,8,9]]), especially since Python/SciPy doesn't seem to have a 'blink matching brackets' option. </HERESY> -- Stephen Walton, Professor, Dept. of Physics & Astronomy, Cal State Northridge stephen.walton@csun.edu
Stephen Walton <stephen.walton@csun.edu> writes:
Well, note that a row and column vector is nothing more than a 1xN or Nx1 array (as opposed to a what I'd call a 'flat' N-array).
So [1,2,3] denotes a 'flat' 3-array to Numeric, while [[1,2,3]] denotes 1-by-3 array? Not sure I understand the distinction.
I'm not sure how best to explain this (I don't know your background, other than that you are likely to be pretty clued about math), but I'll try: These are not the same: scalar 1x vector 1x1 matrix 1x1x1 array 1x1x1x1 array 1 --> [1] -> [[1]], [[[1]]], [[[[1]]]] etc. because apart from storing the same single numerical value, they have different information about their structure (viz. how many, if any, axes there are). If this doesn't make sense, try indexing these constructs: 1[0] ==> TypeError as it makes no sense to index a number [1][0] ==> 1 [[1]][0] ==> [1] etc. If you have one index, you index through what's enclosed by the outermost pair of '[',']'s, so: [1,2,3][0] (which I could maybe more clearly write as 3 rows: [1, 2, 3][0] ) is 1 and [[1], [2], [3]][0] is [1], wheras [[1,2,3]][0] is [1,2,3] Does that start to make sense now? In matlab everything really is a matrix, so 1 and [1] are really just a shorthand for [[1]], and indexing is a hack. This is neither pretty nor does it scale well.
I agree that SciPy is awkward for linear algebra, but it's mainly syntax in my case.
I perfectly aggree. I especially find that things like: dot(transpose(X), dot(V, transpose(U))) * x quickly render code completely unreadable. That's why with my matrix class it looks like: X.T ._* (V ._* U.T) * x where the pseudo-operator '._*' is the dot-product.
<HERESY> I find typing 'x=[1,2,3;4,5,6;7,8,9]' much more straightforward than 'x=array([[1,2,3],[4,5,6],[7,8,9]]), especially since Python/SciPy doesn't seem to have a 'blink matching brackets' option. </HERESY>
well this:
from Numeric import dot, array dot(array([[1],[2],[0.00003]]), array([[1,2,3]])) array([[ 1.00000000e+00, 2.00000000e+00, 3.00000000e+00], [ 2.00000000e+00, 4.00000000e+00, 6.00000000e+00], [ 3.00000000e-05, 6.00000000e-05, 9.00000000e-05]])
would become:
from nummat import matrix as mat mat('1;2;0.00003') ._* mat('1,2,3')
matrix(''' 1.00000 2.00000 3.00000 2.00000 4.00000 6.00000 0.00003 0.00006 0.00009 ''') I like to think that both input and output are markedly preferable in the second case (and much more so for complicated expressions) :) (displayed above is matlab style formatting, Numeric.array-style formatting is also an option; plus really large matrices don't clutter up the screen by default, e.g.:
mat.ones((1000,10000)) <1000 x 10000 matrix of type Int32>)
Note that you could also use Matrix.py, which also allows you to write
Matrix('1, 2, 3')
The main advantages over Matrix.py that already comes with Numeric is that my matrix class is (or at least aims to be) completely compatible with Numeric arrays (i.e. you should be able to use one of my matrix objects anywhere where you would you could use a Numeric array (of array rank-2, of course)), provides much more funcationality (among many other things matlab-style output formatting and good syntax for *both* elementwise and matrixwise operations, plus it can use an optional library that makes dot-products for big matrices 40 times or so faster). There are lots of other features and plenty of test-code, but I've lacked the time to package it up and iron out a few things before I put it on the web. There are also at least two disadvantages, a) it needs at lest python 2.2 and b) there is a bug in Numeric that makes it really slow, but I've got a simple and safe patch that fixes that. As I said, I'll be happy to send interested parties a preview of the code. OK, enough with the shameless advertisment for now :) alex -- Alexander Schmolck Postgraduate Research Student Department of Computer Science University of Exeter A.Schmolck@gmx.net http://www.dcs.ex.ac.uk/people/aschmolc/
I'm replying to a long-ago message by Alexander here. I do understand the difference between rank and dimensionality, if I've used the right terms here, and I'm now persuaded that Numarray/Numeric is more mathematically correct than MATLAB, where as Alexander points out, 1, [1] and [[1]] are all the same thing, namely a 1-by-1 matrix. But I want to strongly encourage Alexander to release his matrix package. I really like the ideas which I've kept below from his reply. More to the point, it would help me wean users from MATLAB and IDL to SciPy if they could use his more compact notation. Thanks for listening, Steve Walton On Mon, 2002-11-25 at 12:05, Alexander Schmolck wrote:
from Numeric import dot, array dot(array([[1],[2],[0.00003]]), array([[1,2,3]])) array([[ 1.00000000e+00, 2.00000000e+00, 3.00000000e+00], [ 2.00000000e+00, 4.00000000e+00, 6.00000000e+00], [ 3.00000000e-05, 6.00000000e-05, 9.00000000e-05]])
would become:
from nummat import matrix as mat mat('1;2;0.00003') ._* mat('1,2,3')
matrix(''' 1.00000 2.00000 3.00000 2.00000 4.00000 6.00000 0.00003 0.00006 0.00009 ''')
I like to think that both input and output are markedly preferable in the second case (and much more so for complicated expressions) :) -- Stephen Walton, Professor, Dept. of Physics & Astronomy, Cal State Northridge stephen.walton@csun.edu
I'm replying to a long-ago message by Alexander here. I do understand the difference between rank and dimensionality, if I've used the right terms here, and I'm now persuaded that Numarray/Numeric is more mathematically correct than MATLAB, where as Alexander points out, 1, [1] and [[1]] are all the same thing, namely a 1-by-1 matrix.
But I want to strongly encourage Alexander to release his matrix package. I really like the ideas which I've kept below from his reply. More to the point, it would help me wean users from MATLAB and IDL to SciPy if they could use his more compact notation.
Note, SciPy has matrix functionality already included (borrowed from Numeric actually). Contributions from Alexander should really start from that base. The simple command mat() (a SciPy reference to Matrix.Matrix() from Numeric) will return a matrix object Note you can also define a matrix using MATLAB-like syntax if you enclose it in quotes first.
a = mat('[1,2,3;4,5,6]') print a Matrix([[1,2,3], [4,5,6]])
a.T is the transpose of the matrix a.H is the Hermitian transpose a.I is the inverse a.A is the array equivalent of the Matrix and a*b is matrix multiplication. a**k is matrix power (using an efficient algorithm). I find it a little amusing that everyone is constantly re-inventing the wheel here. Syntax and implementation can always be discussed, but we should discuss it from what is already present. Best regards, -Travis
On Tue, 2002-12-10 at 13:32, Travis Oliphant wrote:
I find it a little amusing that everyone is constantly re-inventing the wheel here. Syntax and implementation can always be discussed, but we should discuss it from what is already present.
Point taken. I'll go away and read some docs now :-) . -- Stephen Walton, Professor, Dept. of Physics & Astronomy, Cal State Northridge stephen.walton@csun.edu
So [1,2,3] denotes a 'flat' 3-array to Numeric, while [[1,2,3]] denotes 1-by-3 array? Not sure I understand the distinction.
The difference is that [[1,2,3]] is a two-dimensional array while [1,2,3] is a one-dimensional arryay. This rank distinction is convenient for some problems and less convenient for matrix algebra problems.
I agree that SciPy is awkward for linear algebra, but it's mainly syntax in my case. <HERESY> I find typing 'x=[1,2,3;4,5,6;7,8,9]' much more straightforward than 'x=array([[1,2,3],[4,5,6],[7,8,9]]), especially since Python/SciPy doesn't seem to have a 'blink matching brackets' option. </HERESY>
There is the option in scipy to use the mat function:
mat('[1,2,3;4,5,6]') Matrix([[1,2,3], [4,5,6]])
This allows that kind of notation input and also gives you a real 2-D matrix where * means matrix-multiplication. -Travis Oliphant
participants (4)
-
Alexander Schmolck -
Perry Greenfield -
Stephen Walton -
Travis Oliphant