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