On Dec 26, 2007 11:10 PM, William Stein <[EMAIL PROTECTED]> wrote: > > On Dec 26, 2007 8:51 PM, Mike Hansen <[EMAIL PROTECTED]> wrote: > > > > I had made this a ticket a few days ago: > > http://sagetrac.org/sage_trac/ticket/1587 > > Thanks. I've updated the ticket based on the above discussion, and > suggested that the fix is to improve the documentation. Literally > changing the behavior in that one function, would break dozens > of other functions, at least. > > It might be really useful to have > > sage: A.right_kernel() > > to mean the set of vectors v such that A*v = 0, i.e., the vectors on the > right. > That would have to be clearly documented -- the function itself would > be defined in matrix2.pyx and would just transpose A and call kernel > on the resulting transpose. It would also cache the result. > > We have A.right_eigenvectors() in some cases (e.g., A an RDF matrix), and > the documentation makes the meaning very clear: > > ------------------------------ > > sage: A = random_matrix(RDF,3) > sage: A.right_eigenvectors() > ([1.34856636676, -1.04338481358, -0.208244283695], > [-0.250271326138 0.846883172518 0.0580964218791] > [ 0.884959315834 0.223023546117 -0.702413116863] > [ 0.392697431404 0.48275189278 0.709394543977]) > sage: A.left_eigenvectors() > ([1.34856636676, -1.04338481358, -0.208244283695], > [ -0.51163197441 0.589230432257 0.625332088145] > [ 0.967591994779 0.214539369634 0.133186300037] > [-0.344957735432 -0.460493249193 0.817893714497]) > sage: A.right_eigenvectors? > Type: builtin_function_or_method > Base Class: <type 'builtin_function_or_method'> > String Form: <built-in method right_eigenvectors of > sage.matrix.matrix_real_double_dense.Matrix_real_double_dense object > at 0x2b077b08c3b0> > Namespace: Interactive > Docstring: > > Computes the eigenvalues and *right* eigenvectors of this > matrix m acting *from the left*. I.e., vectors v such that > m * v = lambda*v, where v is viewed as a column vector. > ------------------------------ > > > > It actually might be possible to define > > sage: A.left_kernel() > > and > > sage: A.right_kernel() > > and have > > sage: A.kernel() > > default to A.right_kernel() without breaking sage into a million pieces. > One would first define only A.left_kernel and A.right_kernel. Then > one would go through all of Sage and make sure every instance of > A.kernel where A is a matrix is changed to A.left_kernel -- since that > is what is currently assumed, then doctest everything, and finally > define a function kernel() in matrix2.pyx, which just calls > self.right_kernel().
I vote +1 to add .right_kernel(), left_kernel(), and .right_eigenspaces, left_eigenspaces. I have no strong feelings of how they behave in the default though. > > This would of course break code not in Sage that relies on the current > behavior, which is not desirable, but not a deal breaker either at this > stage in Sage development. > > Since x*A and A*x are both defined for x = vector(...), I think this > would be reasonable. > > > Another possibility would be to *only* define A.left_kernel() and > A.right_kernel() and deprecate A.kernel(). That seems a little > too anal to me. > > If we decide to do the above, what are the other similar functions to > worry about? > Certainly eigenspaces.... An option is to add column_echelon in addition to echelon (ie, row_echelon). This is another left vs right thing. > > Since this issue has come up _numerous_ times I've made a trac > ticket for it: > http://trac.sagemath.org/sage_trac/ticket/1607 > > > -- William > > > > > On 12/26/07, William Stein <[EMAIL PROTECTED]> wrote: > > > > > > On Dec 26, 2007 7:35 PM, Marshall Hampton <[EMAIL PROTECTED]> wrote: > > > > > > > > At least in the United States, and I assume some other places as well, > > > > matrices are usually considered to act from the left. So the kernel > > > > of a matrix A would be the set of vectors x such that Ax = 0. In > > > > sage, the kernel is given for the matrix acting from the right, i.e. > > > > the set of vectors y such that yA = 0. If there is compelling > > > > argument as to why that makes sense, I can live with it. > > > > > > There are 2 or 3 reasons why things are as they are with matrix > > > actions on vectors in Sage. > > > > > > 1. In Sage vectors are row vectors: > > > sage: v = vector([1,2,3]) > > > sage: v > > > (1, 2, 3) # <-- that's a row > > > > > > Matrices act naturally from the right on row vectors. > > > > > > Nonetheless, we now allow both actions in Sage for convenience: > > > > > > sage: A = random_matrix(QQ,3) > > > sage: A*v > > > (5, -4, 3) > > > sage: v*A > > > (6, 3/2, -1) > > > > > > 2. David Kohel and I made the decision about which side matrices would > > > act on > > > when I started Sage, i.e., back when Sage was called "Software for > > > Arithmetic > > > Geometry Experimentation", and the main goal of Sage was to provide a > > > viable > > > open source alternative to the subset of Magma that David Kohel and I > > > used, and > > > to do so in a way that made it as easy as possible to port our code from > > > Magma, > > > and to go back and forth between Sage and Magma. > > > In Magma matrices act from the right, probably because vectors are row > > > vectors > > > and also because Magma is Australian. > > > > > > 3. At some point I was about to change everything to matrices acting from > > > the > > > left, and David Kohel stopped me. > > > > > > I don't know if that is a compelling enough reason. A fourth reason is > > > that > > > changing things now would be really really really hard, and would likely > > > introduce numerous bugs all over the place. > > > > > > A Magma example: > > > ----- > > > > > > sage: A = random_matrix(QQ,3) > > > sage: v = vector([1,2,3]) > > > sage: v*A > > > (9, 4, 3/2) > > > sage: A*v > > > (-5, 2, 15/2) > > > sage: aa = magma(A) > > > sage: vv = magma('VectorSpace(RationalField(),3)![1,2,3]') # trac > > > 1605 -- I'm on it. > > > sage: vv*aa > > > ( 9 4 3/2) > > > sage: aa*vv > > > ... (boom!) > > > <type 'exceptions.TypeError'>: Error evaluation Magma code. > > > IN:_sage_[7] := _sage_[4] * _sage_[5]; > > > OUT: > > > >> _sage_[7] := _sage_[4] * _sage_[5]; > > > ^ > > > Runtime error in '*': Arguments are not compatible > > > Argument types given: AlgMatElt[FldRat], ModTupFldElt[FldRat] > > > > > > > > > > But the > > > > documentation for kernel() obscures, rather than clarifies, this > > > > issue: > > > > > > > > Docstring: > > > > > > > > Return the kernel of x. > > > > > > > > EXAMPLES: > > > > sage: M = MatrixSpace(QQ,3,3) > > > > sage: A = M([1,2,3,4,5,6,7,8,9]) > > > > sage: kernel(A) > > > > Vector space of degree 3 and dimension 1 over Rational Field > > > > Basis matrix: > > > > [ 1 -2 1] > > > > > > > > The problem with this example is that A is quite an unusual matrix: > > > > its left-kernel is equal to its right-kernel. I recommend that a non- > > > > square example be given that makes the current behavior clearer. > > > > > > Good idea. Please create a trac ticket, then put in some examples. > > > You'll modify the file > > > sage/matrix/matrix_rational_dense.pyx > > > Please put in a bunch (i.e., maybe 4 or 5) of examples to illustrate all > > > kinds of things, including edge cases (0 by n or n by 0 matrices, > > > denominators, etc.). > > > > > > -- William > > > > > > > > > > > > > > > > > > > > > > > -- > William Stein > Associate Professor of Mathematics > University of Washington > http://wstein.org > > > > > --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-support@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-support URLs: http://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~----------~----~----~----~------~----~------~--~---