Re: check if a square matrix is diagonal

*To*: mathgroup at smc.vnet.net*Subject*: [mg115324] Re: check if a square matrix is diagonal*From*: Bill Rowe <readnews at sbcglobal.net>*Date*: Fri, 7 Jan 2011 04:12:40 -0500 (EST)

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 {}.