Re: Extract any diagonal from a square matrix...

*To*: mathgroup at smc.vnet.net*Subject*: [mg66286] Re: Extract any diagonal from a square matrix...*From*: "Ray Koopman" <koopman at sfu.ca>*Date*: Mon, 8 May 2006 00:46:01 -0400 (EDT)*References*: <e3js8r$8kh$1@smc.vnet.net>*Sender*: owner-wri-mathgroup at wolfram.com

hawkmoon269 wrote: > Trying to put a function together that extracts any one of the > diagonals from a square matrix. Right now I have this -- > > DiagonalT[a_List, d_Integer] := > Tr[Take[Which[Positive[d], a, Negative[d], Transpose[a]], > {1, Length[a] - Abs[d] + 1}, {Abs[d], Length[a]}], List] > > This works, but I thought there might be something less cumbersome. > Essentially, the function constructs a submatrix of the matrix so that > the requested diagonal from the matrix becomes the main diagonal of the > submatrix, which is then retrieved. D is the diagonal to retrieve, > where d = > > 3 -- 2nd superdiagonal > 2 -- 1st superdiagonal > 1 -- main diagonal > -2 -- 1st subdiagonal > -3 -- 2nd subdiagonal > > etc... > > Some other things I've considered -- > > ...rotating the elements of each row until column 1 becomes the > requested diagonal; > ...dropping elements from each row until the first or last element in > each row becomes the next element in the requested diagonal; > ...flattening the matrix and then using Range and Part to retrieve the > requested diagonal. > > Any thoughts...? > > h This follows your basic approach, but with two changes: 1. The method of specifying the diagonal is: e = 2 -- 2nd superdiagonal 1 -- 1st superdiagonal 0 -- main diagonal -1 -- 1st subdiagonal -2 -- 2nd subdiagonal etc... 2. The matrix can be rectangular. For superdiagonals, drop the first e columns. For subdiagonals, drop the first -e rows. Tr can take it from there. takediag[a_?MatrixQ, 0] := Tr[a, List] takediag[a_?MatrixQ, e_Integer?Positive]/; e < Length@a[[1]] := Tr[Drop[#,e]&/@a], List] takediag[a_?MatrixQ, e_Integer?Negative]/; -e < Length@a := Tr[Drop[a,-e], List]