Re: check if a square matrix is diagonal

*To*: mathgroup at smc.vnet.net*Subject*: [mg115347] Re: check if a square matrix is diagonal*From*: Andrzej Kozlowski <akoz at mimuw.edu.pl>*Date*: Sat, 8 Jan 2011 03:39:32 -0500 (EST)

On 7 Jan 2011, at 10:12, Bill Rowe wrote: > On 1/6/11 at 2:06 AM, xiaochu at gmail.com (benyaya) wrote: > >> What I try to do is extract the diagonal, subtract if from the >> matrix, then compare the new matrix with 0. My code doesn't work out >> though, can anyone help? thanks a lot. > >> checkIfDiagonalMatrix[m_] = Module[{d, mtemp}, >> d = Dimensions[m]; >> mtemp = DiagonalMatrix[Diagonal[m]] - m; >> If[mtemp == Table[Table[0, {i, 1, d}], {i, 1, d}], >> True, >> False] >> ] > > One immediate problem is Dimensions[m] returns a list. > Consequently, d cannot be used as the end point for the Table > iterator. The following will do what you want and has the same > logic as you have used > > checkIfDiagonalMatrix[m_] := Module[{d, mtemp}, > d = Dimensions[m]; > mtemp = DiagonalMatrix[Diagonal[m]] - m; > If[mtemp == ConstantArray[0,d], > True, > False] > ] > > Note, I used SetDelayed (:=) not Set (==) > > But I think this logic is doing more work than necessary. I > would accomplish this as: > > diagonalQ[ > m_] := (ArrayRules[SparseArray@m] /. > HoldPattern[{a_, a_} -> _] :> Sequence[]) = {} > > If m is a diagonal matrix this should be pretty fast. However, > it m is a dense array, this might be fairly slow. > > What I am doing is using ArrayRules to extract all of the > non-zero elements of m. Those are returned as rules that look > like {m,n}->number. I then apply a pattern matching rule that > deletes all cases where m and n are equal and compare that to > the empty list {}. > > An simpler approach is: diagonalQ[m_] := UpperTriangularize[m] = LowerTriangularize[m] This is slower for diagonal matrices but very much faster for non-diagonal ones. Andrzej Kozlowski