Sorry if the speed of that seemed rude. I just happened to be checking
my email when that ticket came in. :-)
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
-- Umberto Eco
I'm not subscribed to the numpy list, so I didn't see that message,
but would you recommend that SymPy use the same syntax as numpy? Can
you perhaps give some of the reasoning behind numpy's syntax?
Aaron Meurer
--
You received this message because you are subscribed to the Google Groups "sympy" group.
To post to this group, send email to sy...@googlegroups.com.
To unsubscribe from this group, send email to sympy+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sympy?hl=en.
Well, numpy.matrix has to interact with numpy.ndarrays and thus has to
deal with issues that sympy.Matrix may not. numpy.array([1,2,3]) is
treated as a row-vector in most contexts when it is mixed with rank-2
arrays due to numpy's broadcasting semantics. numpy.matrix() is not
just used as a constructor from list literals, it also converts
ndarray objects to matrix objects when such conversions need to be
done implicitly.
[~]
|1> va = np.array([1,2,3])
[~]
|2> ma = np.arange(9).reshape([3,3])
[~]
|3> va
array([1, 2, 3])
[~]
|4> ma
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
[~]
|5> va + ma
array([[ 1, 3, 5],
[ 4, 6, 8],
[ 7, 9, 11]])
[~]
|6> vm = np.matrix([1,2,3])
[~]
|7> vm
matrix([[1, 2, 3]])
[~]
|8> np.matrix(va)
matrix([[1, 2, 3]])
[~]
|9> mm = np.matrix(va)
[~]
|10> mm
matrix([[1, 2, 3]])
[~]
|11> mm = np.matrix(ma)
[~]
|12> mm
matrix([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
[~]
|14> va + mm
matrix([[ 1, 3, 5],
[ 4, 6, 8],
[ 7, 9, 11]])
[~]
|15> vm + mm
matrix([[ 1, 3, 5],
[ 4, 6, 8],
[ 7, 9, 11]])
Even if we did agree that numpy.matrix() *ought* to behave differently
if we were designing it again, the code has been out in the wild for
many, many years. Changing it now would break a lot of code that
depends on the current semantics. We simply can't change it now.
That's why I closed the ticket without input from the rest of the
devs. It's just a non-starter.
I can't make a recommendation for SymPy one way or the other. The
numpy.matrix() semantics are the way they are for reasons internal to
numpy. What you need to consider is how important it is to you to
match numpy's semantics. I don't really know if there are use cases
are for going back and forth between the two types or if the only
concern is having similar semantics for pedagogical reasons.
Maintaining internal consistency inside SymPy may be more important.
Either way is a reasonable choice.
Thanks for letting me know why a reply was in my box almost the second
after I pressed the return key :-) I did search the tickets and didn't
find a similar issue but I figured you must have been through this
already. Your need to maintain legacy compatibility is understandable.
/c
I've got a proposal nearly ready:
--we let Matrix([1,2,3]) give a row vector so it's compatible with numpy;
--we drop the requirement (but still allow0 the bounding brackets (so
it's still compatible with numpy but also behaves like sympy Set and
Tuple);
--we introduce the Vector(1,2,3) or Vector(*[1,2,3]) as the
alternative to Matrix([1,2,3]).T which a) gives an easy fix to
existing code where Matrix([1,2,3]) might be hard to find. (If it's
split over many lines, the head should still be easy to find and can
be changed from Matrix([ to Vector(*[ and b) gives a meaningful and
transparent alias for Matrix([1,2,3]).T
What do you think? https://github.com/sympy/sympy/pull/581
Also, there are some interface tidying changes and docstrings added to
dot and projection. I would really appreciate it if someone woring
often with matrices would check that I've done the right things there.
/c
So I think we need to consider things from the SymPy point of view,
like you said. One thing to consider is that eventually we will have
an ImmutableMatrix(), which is Basic, but which will have the same
syntax as Matrix(). So it will need to satisfy the
ImmutableMatrix(*args) invariant.
We also should consider backwards compatibility breaks of our own.
Changing Matrix([1, 2, 3]) to a row vector will break a lot of code.
Aaron Meurer
So do you think no change should take place or do you think having
Matrix and others (Set, Tuple, Dict) behave the same way -- not wrap
their args in a container -- is important?
/c
The main reason it's important for these classes is that if you make
Tuple([1]) == Tuple(1), then you can't create a nested Tuple, i.e.,
Tuple(Tuple(1)) would just be reduced to Tuple(1).
So the question is, if you would ever want to create a nested Matrix?
I think you might, with some kind of block matrix, though I'm not so
sure that it's as important that it doesn't automatically denest in
this case. What do others think?
Aaron Meurer
>
> /c
I don't think we should add more special cases. The Matrix constructor
is already excessively complex. Besides, handling iterables and
non-iterables in different ways is fraught with problems: what'll happen
when we want a Matrix whose elements are iterable (for instance some
kind of polynomial object)??
That's why I was wondering about nested matrices. Also, for Matrix(1,
2, 3), allowing this might limit future syntaxes. So contrary to what
I just said, I'm not so sure if allowing that is a good idea or not at
this point. We definitely should keep Matrix([1, 2, 3]) as it is,
though.
Aaron Meurer
On Thu, Sep 1, 2011 at 6:16 AM, smichr <smi...@gmail.com> wrote:
> OK, it looks like the instantiation is not going to change. Could
> someone interested in Matrix take a look at the other changes:
>
> All indices (except absolute indices) behave like indices to python
> lists. So negative indices are now supported:
> M[1,-1] gives the last element of row 1
> col_insert(-1, c) inserts c before last column
> col_insert(M.cols, c) will append c (since M.cols is greater than the
> last column number)
> col_insert(oo, c) will append c (since oo is greater than the last
> column number)
I am +1 to all of these (though I haven't looked at any code).
>
> The dot product is a little more flexible, returning a list if given
> anything other than a single row or col
I don't know if that's a great idea. You can just do matrix
multiplication if you want multiple dot products (and it may even be
faster).
>
> project and dot docstrings are expanded
>
> coverage has been increased
>
> arguments to zeros and ones can be given as foo(i, j) and not only
> foo((i,j)) and foo(i)
We ought to deprecate foo((i, j)).
Aaron Meurer
It always does matrix multiplication now. It just puts the results in
a list (if more than one dot was done) or returns the single scalar
(which is the current expectation).