From: David N. <da...@di...> - 2006-10-11 08:09:31
|
Hi, i'm moving some old perl PDL code to python. I've come across a line which changes values in a diagonal line accross a matrix. matrix.diagonal() returns a list of values, but making changes to these does not reflect in the original (naturally). I'm just wondering if there is a way that i can increment all the values along a diagonal? Cheers Dave P.S i wasnt sure how to sign to the mailing list - so i'd appreciate being CC'd in any replies ;) |
From: Johannes L. <a.u...@gm...> - 2006-10-11 08:35:47
|
> I'm just wondering if there is a way that i can increment all the values > along a diagonal? Assume you want to change mat. # min() only necessary for non-square matrices index = arange(min(mat.shape[0], mat.shape[1])) # add 1 to each diagonal element matrix[index, index] += 1 # add some other stuff matrix[index, index] += some_array_shaped_like_index HTH, Johannes |
From: David N. <da...@di...> - 2006-10-11 23:34:49
|
Johannes Loehnert wrote: >> I'm just wondering if there is a way that i can increment all the values >> along a diagonal? >> > > Assume you want to change mat. > > # min() only necessary for non-square matrices > index = arange(min(mat.shape[0], mat.shape[1])) > # add 1 to each diagonal element > matrix[index, index] += 1 > # add some other stuff > matrix[index, index] += some_array_shaped_like_index > > > HTH, Johannes > > Thank you very much for the prompt reply, I'm just having a problem with this method: This method appears to only work if the matrix is mxm for example: >>> zeros((5,5)) array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]) >>> x = zeros((5,5)) >>> index = arange(min(x.shape[0],x.shape[1])) >>> x[index,index] += 1 >>> x array([[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]]) >>> This is very nice, exactly what i want, but it doesnt work for mxn matricies: >>> x = zeros((5,3)) >>> x array([[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]) >>> index = arange(min(x.shape[0],x.shape[1])) >>> x[index,index] += 1 >>> x array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 0], [0, 0, 0]]) >>> So the min part is right for mxn matrices - but perhaps there is a way to use the index differently. I'm very new to numpy, so excuse my noobness :) Just for reference, this is the line of perl i'm trying to port: (my $dummy = $ones->diagonal(0,1))++; # ones is a matrix created with zeroes() Yes, i know it is horribly ugly, but in this case, diagonal returns a list of references to the values in the original matrix, so values can be changed in place. I much prefer python - hence the port, but it seems like a hard thing to replicate. Perhaps there could be a function that returns an iterator over the values in a matrix and returns the index's. like: for index in diag_iter(matrix,*axes): matrix[index] +=1 Once again, cheers - i hope we can figure something out :) Dave Novakovic PS: If anyone would care to link me to the subscription page for the mailing list so you dont have to CC me all the time :) |
From: Bill B. <wb...@gm...> - 2006-10-11 23:58:47
|
On 10/12/06, David Novakovic <da...@di...> wrote: > Johannes Loehnert wrote: > This is very nice, exactly what i want, but it doesnt work for mxn > matricies: > > >>> x = zeros((5,3)) > >>> x > array([[0, 0, 0], > [0, 0, 0], > [0, 0, 0], > [0, 0, 0], > [0, 0, 0]]) > >>> index = arange(min(x.shape[0],x.shape[1])) > >>> x[index,index] += 1 > >>> x > array([[1, 0, 0], > [0, 1, 0], > [0, 0, 1], > [0, 0, 0], > [0, 0, 0]]) Exactly what output are you expecting? That is the definition of the 'diagonal' for a non-square matrix. If you're expecting something else then what you want is not the diagonal. > Just for reference, this is the line of perl i'm trying to port: > > > like: > > for index in diag_iter(matrix,*axes): > matrix[index] +=1 That's not going to change the mathematical definition of the diagonal of a non-square matrix. > PS: If anyone would care to link me to the subscription page for the > mailing list so you dont have to CC me all the time :) Check the bottom of this message. > _______________________________________________ > Numpy-discussion mailing list > Num...@li... > https://lists.sourceforge.net/lists/listinfo/numpy-discussion > --bb |
From: David N. <da...@di...> - 2006-10-12 00:21:14
|
Thanks for the help, i've learnt a lot and also figured out something that does what I want, i'll paste an interactive session below: x = zeros((4,7)) x array([[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]) index = arange(min(x.shape[0], x.shape[1])) index2 = copy.deepcopy(index) #deep copy may be overkill for a,b in enumerate(index): ... index2[a] += a ... if len(x[:,0]) > len(x[0]): ... x[index2,index] +=1 ... else: ... x[index,index2] +=1 ... x array([[1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 1]]) Thanks for the tips Dave Novakovic P.S. subscribed to the list now Bill Baxter wrote: > Forgot to CC you... > > ---------- Forwarded message ---------- > From: Bill Baxter <wb...@gm...> > Date: Oct 12, 2006 8:58 AM > Subject: Re: [Numpy-discussion] incrementing along a diagonal > To: Discussion of Numerical Python > <num...@li...> > > > On 10/12/06, David Novakovic <da...@di...> wrote: >> Johannes Loehnert wrote: >> This is very nice, exactly what i want, but it doesnt work for mxn >> matricies: >> >> >>> x = zeros((5,3)) >> >>> x >> array([[0, 0, 0], >> [0, 0, 0], >> [0, 0, 0], >> [0, 0, 0], >> [0, 0, 0]]) >> >>> index = arange(min(x.shape[0],x.shape[1])) >> >>> x[index,index] += 1 >> >>> x >> array([[1, 0, 0], >> [0, 1, 0], >> [0, 0, 1], >> [0, 0, 0], >> [0, 0, 0]]) > > Exactly what output are you expecting? That is the definition of the > 'diagonal' for a non-square matrix. If you're expecting something > else then what you want is not the diagonal. > >> Just for reference, this is the line of perl i'm trying to port: >> >> >> like: >> >> for index in diag_iter(matrix,*axes): >> matrix[index] +=1 > > That's not going to change the mathematical definition of the diagonal > of a non-square matrix. > >> PS: If anyone would care to link me to the subscription page for the >> mailing list so you dont have to CC me all the time :) > > Check the bottom of this message. > >> _______________________________________________ >> Numpy-discussion mailing list >> Num...@li... >> https://lists.sourceforge.net/lists/listinfo/numpy-discussion >> > > --bb > |
From: David N. <da...@di...> - 2006-10-12 00:36:16
|
David Novakovic wrote: > Thanks for the help, i've learnt a lot and also figured out something > that does what I want, i'll paste an interactive session below: > > x = zeros((4,7)) > x > array([[0, 0, 0, 0, 0, 0, 0], > [0, 0, 0, 0, 0, 0, 0], > [0, 0, 0, 0, 0, 0, 0], > [0, 0, 0, 0, 0, 0, 0]]) > index = arange(min(x.shape[0], x.shape[1])) > index2 = copy.deepcopy(index) #deep copy may be overkill > for a,b in enumerate(index): > ... index2[a] += a > Turns out this is not good at all. I guess I'm still open to suggestions then :( Dave > ... > if len(x[:,0]) > len(x[0]): > ... x[index2,index] +=1 > ... else: > ... x[index,index2] +=1 > ... > x > array([[1, 0, 0, 0, 0, 0, 0], > [0, 0, 1, 0, 0, 0, 0], > [0, 0, 0, 0, 1, 0, 0], > [0, 0, 0, 0, 0, 0, 1]]) > > > Thanks for the tips > > Dave Novakovic > > P.S. subscribed to the list now > > Bill Baxter wrote: > >> Forgot to CC you... >> >> ---------- Forwarded message ---------- >> From: Bill Baxter <wb...@gm...> >> Date: Oct 12, 2006 8:58 AM >> Subject: Re: [Numpy-discussion] incrementing along a diagonal >> To: Discussion of Numerical Python >> <num...@li...> >> >> >> On 10/12/06, David Novakovic <da...@di...> wrote: >> >>> Johannes Loehnert wrote: >>> This is very nice, exactly what i want, but it doesnt work for mxn >>> matricies: >>> >>> >>>>>> x = zeros((5,3)) >>>>>> x >>>>>> >>> array([[0, 0, 0], >>> [0, 0, 0], >>> [0, 0, 0], >>> [0, 0, 0], >>> [0, 0, 0]]) >>> >>>>>> index = arange(min(x.shape[0],x.shape[1])) >>>>>> x[index,index] += 1 >>>>>> x >>>>>> >>> array([[1, 0, 0], >>> [0, 1, 0], >>> [0, 0, 1], >>> [0, 0, 0], >>> [0, 0, 0]]) >>> >> Exactly what output are you expecting? That is the definition of the >> 'diagonal' for a non-square matrix. If you're expecting something >> else then what you want is not the diagonal. >> >> >>> Just for reference, this is the line of perl i'm trying to port: >>> >>> >>> like: >>> >>> for index in diag_iter(matrix,*axes): >>> matrix[index] +=1 >>> >> That's not going to change the mathematical definition of the diagonal >> of a non-square matrix. >> >> >>> PS: If anyone would care to link me to the subscription page for the >>> mailing list so you dont have to CC me all the time :) >>> >> Check the bottom of this message. >> >> >>> _______________________________________________ >>> Numpy-discussion mailing list >>> Num...@li... >>> https://lists.sourceforge.net/lists/listinfo/numpy-discussion >>> >>> >> --bb >> >> > > > ------------------------------------------------------------------------- > Using Tomcat but need to do more? Need to support web services, security? > Get stuff done quickly with pre-integrated technology to make your job easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > Numpy-discussion mailing list > Num...@li... > https://lists.sourceforge.net/lists/listinfo/numpy-discussion > > |
From: Johannes L. <a.u...@gm...> - 2006-10-12 06:40:59
|
Hi, I absolutely do not know perl, so I do not know what the expression you posted does. However, the key is just to understand indexing in numpy: if you have a matrix mat and index arrays index1, index2 with, lets say, index1 = array([ 17, 19, 29]) index2 = array([ 12, 3, 9]) then the entries of the index arrays are used as row and column indices respectively, and the result will be an array shaped like the index arrays. So doing mat[index1, index2] will give you --> array([ mat[17, 12], mat[19, 3], mat[29, 9]]). Now if you want the diagonal of a 3x3-mat, you need index1=index2=array([ 0, 1, 2]). mat[index1, index2] --> array([ mat[0,0], mat[1,1], mat[2,2]]) That is what my code does. If you need other, arbitrary subsets of mat, you just have to fill the index arrays accordingly. Johannes |
From: Travis O. <oli...@ie...> - 2006-10-12 02:43:40
|
David Novakovic wrote: > Hi, > > i'm moving some old perl PDL code to python. I've come across a line > which changes values in a diagonal line accross a matrix. > > matrix.diagonal() returns a list of values, but making changes to these > does not reflect in the original (naturally). > > I'm just wondering if there is a way that i can increment all the values > along a diagonal? > You can refer to a diagonal using flattened index with a element-skip equal to the number of columns+1. Thus, a.flat[::a.shape[1]+1] += 1 will increment the elements of a along the main diagonal. -Travis |