Re: Extract any diagonal from a square matrix...
- To: mathgroup at smc.vnet.net
- Subject: [mg66357] Re: Extract any diagonal from a square matrix...
- From: Bill Rowe <readnewsciv at earthlink.net>
- Date: Wed, 10 May 2006 06:34:41 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
On 5/9/06 at 2:34 AM, mukasa at jeol.com (Sseziwa Mukasa) wrote: >On May 8, 2006, at 12:46 AM, Bill Rowe wrote: >>On 5/6/06 at 11:50 PM, rson at new.rr.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] >>[deleted] >>Another possible approach would be to use SparseArray. For example, >>the 1st superdiagonal can be obtained as follows: >> In[21]:= >> a=Table[10i +j,{i,4},{j,4}]; >> b=SparseArray[{i_,j_}:>1/;j==i+1,{4,4}]; >> SparseArray[a b]/.SparseArray[_,_,_,a_]:>Last@a >>Out[23]= {12,23,34} >>This can be generalized to extract an arbitrary diagonal by >>changing b to be >>b=SparseArray[{i_,j_}:>1/;j==i+d] where >I am also going to use this convention because it makes life >simpler: >>d= >> 2 -- 2nd superdiagonal >> 1 -- 1st superdiagonal >> 0 -- main diagonal >> -1 -- 1st subdiagonal >> -2 -- 2nd subdiagonal >Separating it into two cases: >DiagonalT[a_?MatrixQ,d_?NonNegative]:=Table[a[[i,i+d]],{i,First >[Dimensions[a]]-d}] >DiagonalT[a_?MatrixQ,d_?Negative]:=Table[a[[i-d,i]],{i,First >[Dimensions[a]]+d}] On re-reading my suggestion, I realized the multiplication and intermediate matrix are not needed. That is the problem can be solve as: DiagonalT[(a_)?MatrixQ, d_Integer] := Module[{m = Length[a]}, SparseArray[{i_, j_} :> a[[i,j]] /; j == i + d, {m, m}] /. SparseArray[_, _, _, x_] :> Last[x]] But a check of the performance shows your code is much faster. In fact on my machine your code extracts the main diagonal about 20% faster than Tr[a,List] which probably means your code is close to optimum. -- To reply via email subtract one hundred and four