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