See also 'elementary_row_op' and consider storing the string hints as 'mul, 
swap, add' and redefine (for typing convenience) the method as `do`:

mul = "n->kn"
swap = "n<->m"
add = "n->n+km"
Matrix.do = Matrix.elementary_row_op
e=eye(3)
assert e.do(mul, 0, 5) == Matrix([[5, 0, 0], [0, 1, 0], [0, 0, 1]])
assert e.do(swap, 0, 1) == Matrix([[0, 1, 0], [1, 0, 0], [0, 0, 1]])
assert e.do(add, 0, 5, 1) == Matrix([[1, 5, 0], [0, 1, 0], [0, 0, 1]])

In an interactive session you can keep using the `_` to refer to the last 
output so

eye(3)
_.do(mul, 0, 5)
_.do(swap, 0, 1)
_.do(add, 0, 3, 2)

will produce, as the last output,

Matrix([[0, 1, 3], [5, 0, 0], [0, 0, 1]])

/c
On Friday, November 4, 2022 at 8:51:05 PM UTC-5 pwil...@tkc.edu wrote:

> 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 smi...@gmail.com 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 
>>> <oscar.j....@gmail.com> wrote: 
>>> > 
>>> > On Fri, 4 Nov 2022 at 14:23, Phil Williams <pwil...@tkc.edu> 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 sympy+un...@googlegroups.com. 
>>> > 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 sympy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/73dfb06a-e31e-4089-87b3-4cfe8e04f64dn%40googlegroups.com.

Reply via email to