Re: check if a square matrix is diagonal

*To*: mathgroup at smc.vnet.net*Subject*: [mg115405] Re: check if a square matrix is diagonal*From*: DrMajorBob <btreat1 at austin.rr.com>*Date*: Mon, 10 Jan 2011 02:38:13 -0500 (EST)

The sparse-array example ran so fast (on my machine) that it doesn't matter which method you use: m = SparseArray[Band[{1, 1}] -> RandomReal[1, {10000}]]; Timing[UpperTriangularize[m] == LowerTriangularize[m]] {0.000874, True} Timing[Total[Unitize@m, 2] == Total[Unitize@Diagonal[m]]] {0.000417, True} Timing[m == DiagonalMatrix[Diagonal@m]] {0.000559, True} But that's not a general diagonal matrix, which might be something like: m = Developer`ToPackedArray@ Normal@SparseArray[Band[{1, 1}] -> RandomReal[1, {10000}]]; (THAT step was very slow!) Timing[UpperTriangularize[m] == LowerTriangularize[m]] {6.83235, True} Timing[Total[Unitize@m, 2] == Total[Unitize@Diagonal[m]]] {37.1641, True} Timing[m == DiagonalMatrix[Diagonal@m]] {4.2555, True} But ToPackedArray failed, probably because some entries are Real and others are Integer: Developer`PackedArrayQ@m False If all were Integer, then: m = Developer`ToPackedArray@ Normal@SparseArray[Band[{1, 1}] -> RandomInteger[1, {10000}]]; (That step was very slow again.) Timing[UpperTriangularize[m] == LowerTriangularize[m]] {1.53933, True} Timing[Total[Unitize@m, 2] == Total[Unitize@Diagonal[m]]] {0.812106, True} Timing[m == DiagonalMatrix[Diagonal@m]] {0.660954, True} Developer`PackedArrayQ@m True Similarly with real entries: Timing[m == DiagonalMatrix[Diagonal@m]] {0.866862, False} m = Developer`ToPackedArray@ N@Normal@SparseArray[Band[{1, 1}] -> RandomReal[1, {10000}]]; (That step was very slow again.) Timing[UpperTriangularize[m] == LowerTriangularize[m]] {3.26553, True} Timing[Total[Unitize@m, 2] == Total[Unitize@Diagonal[m]]] {1.07388, True} {1.088817000000006`, True} Timing[m == DiagonalMatrix[Diagonal@m]] {1.34731, True} Developer`PackedArrayQ@m True Bobby On Sun, 09 Jan 2011 01:17:54 -0600, Bill Rowe <readnews at sbcglobal.net> wrote: > On 1/8/11 at 3:39 AM, akoz at mimuw.edu.pl (Andrzej Kozlowski) wrote: > > >> An simpler approach is: > >> diagonalQ[m_] := UpperTriangularize[m] = LowerTriangularize[m] > >> This is slower for diagonal matrices but very much faster for >> non-diagonal ones. > > Even simpler is the suggestion Dr Bob made: > > m==DiagonalMatrix[Diagonal@m] > > And after I had made my post I thought of something else that > seems fast which is > > Total[Unitize@m,2]==Total[Unitize@Diagonal[m]] > > It terms of speed for non-diagonal matrices, the simple method > suggested by Dr Bob is the fastest > > In[1]:= m = RandomReal[1, {10000, 10000}]; > > In[2]:= Timing[UpperTriangularize[m] == LowerTriangularize[m]] > > Out[2]= {2.51418,False} > > In[3]:= Timing[Total[Unitize@m, 2] == Total[Unitize@Diagonal[m]]] > > Out[3]= {1.09644,False} > > In[4]:= Timing[m == DiagonalMatrix[Diagonal@m]] > > Out[4]= {0.770909,False} > > But for a diagonal matrix > > In[5]:= m = SparseArray[Band[{1, 1}] -> RandomReal[1, {10000}]]; > > In[6]:= Timing[UpperTriangularize[m] == LowerTriangularize[m]] > > Out[6]= {0.099239,True} > > In[7]:= Timing[Total[Unitize@m, 2] == Total[Unitize@Diagonal[m]]] > > Out[7]= {0.049362,True} > > In[9]:= Timing[m == DiagonalMatrix[Diagonal@m]] > > Out[9]= {0.067637,True} > > It appears using Total and Unitize to count the non-zero entries > of m is faster. > > it would seem > > -- DrMajorBob at yahoo.com