Thank you all for the responses! This is all very helpful. Jonathan: I'll check out Algebra-with-Sympy. Looks interesting. Thanks for sharing.
Oscar and Aaron: a bit on what I'm doing in the class. My approach is basically to convince them that using Python and Jupyter is easier and more powerful than using a graphing calculator, and will be more useful training to them in the long run. It's fundamentally a math class though, light on the actual programming. I don't want to make them do anything that's harder than using their ti-89 or whatever. And so anything that makes them prefer to reach for the calculator because it's "easier" is something I want to find a way around. They want to be able to do the row operations in place step by step, like they can on their calculator. So mutable operations defined as simple methods (or as functions) works well towards these ends. That said, I really do like the slicing approach too. Perhaps I can convince them it's actually a better way to think of the row operations. I may try it out on them as an alternative, and see if they take to it. Chris: this is *very *helpful, I didn't actually know you can do this. Good to know. I'll explore the workflow and maybe even go ahead and try to do a pull request. On Friday, November 4, 2022 at 9:28:40 PM UTC-4 [email protected] wrote: > Instead of redefining the class, why not use Python's ability to modify > the class directly. Use the built-in `row_op` in the sugar you wish to add: > > >>> row_add = lambda M,i,j,m=1: M.row_op(i,lambda v,k: v+m*M[j,k]) > >>> Matrix.row_add = row_add > >>> N = eye(3) > >>> N.row_add(0,1); N > Matrix([[1, 1, 0], [0, 1, 0], [0, 0, 1]]) > >>> N.row_add(0,1,2); N > Matrix([[1, 3, 0], [0, 1, 0], [0, 0, 1]]) > > /c > On Friday, November 4, 2022 at 1:22:10 PM UTC-5 Aaron Meurer wrote: > >> On Fri, Nov 4, 2022 at 11:28 AM Oscar Benjamin >> <[email protected]> wrote: >> > >> > On Fri, 4 Nov 2022 at 14:23, Phil Williams <[email protected]> wrote: >> > >> > Hi Phil, >> > >> > > I use sympy for matrix calculations in my Finite Math class that I >> teach. I have students working in a Jupyter Notebook. What I want is a >> student-friendly interface for in-place row operations on matrices, so that >> they can work problems step by step that require these operations (e.g. >> solving systems by row reduction). Right now the Matrix class in sympy has >> methods row_swap, and row_op. The former, row_swap is fine, but row_op has >> a general functorial definition that is too advanced for them. I want >> instead row_add and row_mult methods that specify the basic data of the >> operation as inputs (e.g. for row_add, source row, target row, and factor >> that the source row gets multiplied by before adding to target), and >> modifies the matrix in place. >> > > >> > > Right now, I write a bit of code for them to redefine the Matrix >> class and adds these two methods to it, and then have them work with that. >> However, I'm wondering if these methods can be added to sympy. It would be >> useful to them and perhaps others using sympy in a classroom. I'm confident >> I know what needs to be done, but I'm inexperienced with open source and >> I'm not sure where to begin in suggesting this change be incorporated. Just >> exploring this question led me to the idea that posting here might be a >> good first step. Any advice would be appreciated! >> > > Thank you. >> > >> > I agree that row_op has a weird interface. Probably whoever wrote that >> > thought that it's good to try to make things as general as possible >> > but in fact it's really turning a one liner into something that is >> > more complicated than just writing the code directly without using the >> > row_op method. The Matrix class already has far too many redundant >> > methods though and I'm not sure it's a good idea to add more. If >> > anything I'd rather just remove the row_op method if the interface was >> > being redesigned from scratch. >> >> Personally I think it's fine to have the fundamental row operations as >> basic methods on the matrix class. We already have swap as a method. >> You should open an issue about this on the issue tracker (or start a >> PR if you want to go ahead and implement it). >> >> > >> > It isn't hard to make your own function to do this: >> > >> > def row_mult(M, i, f): >> > """Multiply row i of Matrix M by f in place and return M""" >> > M[i, :] *= f >> > return M >> > >> > That being said, the function is just a one-liner and if you taught >> > the students about the more general concept of slicing then they could >> > do it themselves: >> > >> > In [20]: M = eye(3) >> > >> > In [21]: M[1,:] *= -3 >> > Out[21]: >> > ⎡1 0 0⎤ >> > ⎢ ⎥ >> > ⎢0 -3 0⎥ >> > ⎢ ⎥ >> > ⎣0 0 1⎦ >> > >> > In [22]: M[1,:] -= 2*M[0,:] >> > >> > In [23]: M >> > Out[23]: >> > ⎡1 0 0⎤ >> > ⎢ ⎥ >> > ⎢-2 -3 0⎥ >> > ⎢ ⎥ >> > ⎣0 0 1⎦ >> > >> > If they can understand how that slicing works then they can also >> > translate that to an understanding of many other things in Python like >> > lists, strings, numpy arrays etc because slicing is a fairly >> > ubiquitous idiom in Python. >> > >> > Personally if I was teaching this stuff to students then I think I >> > would want them to make the function or code that does this themselves >> > using a loop so that they can understand the row operation in more >> > elementary algorithmic terms. Obviously that depends on exactly what >> > you're trying to teach so I'm not saying that your approach there is >> > wrong in any way. What I am saying though is that there are many >> > different ways that things like this could be taught and I'm not sure >> > we should add methods to the Matrix class to accommodate one >> > particular way. >> >> You can also consider whether it makes sense to use a mutating >> operation like this or to return a new matrix. SymPy matrices are >> mutable by default, but this is different from every other SymPy >> object. The usual way to work with SymPy expressions is to return a >> new expression. Maybe this is a little more complicated to do, which >> is why it might make sense to have these as methods on matrix. >> >> Either way, though, I agree with Oscar that if a method is missing >> from Matrix or any other SymPy class, you are better off just defining >> it as a function rather than trying to subclass the class to add it as >> a method. >> >> Aaron Meurer >> >> > >> > -- >> > Oscar >> > >> > -- >> > You received this message because you are subscribed to the Google >> Groups "sympy" group. >> > To unsubscribe from this group and stop receiving emails from it, send >> an email to [email protected]. >> > To view this discussion on the web visit >> https://groups.google.com/d/msgid/sympy/CAHVvXxSgP5%3DudLruO6a%3Da%3DHPrJW9soJVxChNUrENs73juLiYFw%40mail.gmail.com. >> >> >> > -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/8914f689-7df7-40bb-b1ce-891f4f468e58n%40googlegroups.com.
