5
$\begingroup$

I have a huge matrix defined using constant array function and it allocates so much memory preventing the calculation. Therefore, I would like to change the constant array matrix into sparse matrix which stores only nonzero elements enables reducing the memory size.

Here is just a simple example. Let's say I have a constant array deneme and convert it into sparse matrix deneme2 as below:

deneme = ConstantArray[0, {3, 3}];


deneme[[1, 1]] = 6; deneme[[1, 2]] = 3; deneme[[1, 3]] = 5; 
deneme[[2, 1]] = 4; deneme[[2, 2]] = 7; deneme[[2, 3]] = 8; 
deneme[[3, 1]] = 1; deneme[[3, 2]] = 5; deneme[[3, 3]] = 9;


deneme2 = SparseArray[deneme];

How could I see the total memory the two matrices, deneme and deneme2 allocate?

Does ByteCount work correctly, since the sparse matrix stores much more byte than constant array matrix ?

$\endgroup$
2
  • 3
    $\begingroup$ Did you try searching the documentation? Didn't you come across ByteCount? . Try ByteCount/@ {deneme, deneme2}. Does this answer your question? How to relate memory usage with occupied positions of SparseArrays? $\endgroup$
    – rhermans
    Feb 1 at 9:15
  • $\begingroup$ @rhermans, thank you for your suggestion. However, does ByteCount work correctly, since the sparse matrix stores much more byte than constant array matrix ? I know that sparse matrix stores less memory ? $\endgroup$ Feb 1 at 9:23

1 Answer 1

6
$\begingroup$

You could have found in the documentation a section about Memory Measurement & Optimization.

enter image description here

The first entry is ByteCount.

To measure the memory use you can Map ByteCount over a list of the cases of interest.

ByteCount/@ {deneme, deneme2}

In your case you will find there is no memory use advantage. Why?

SparseArray has an overhead, and it will use more or less memory depending on the size of the matrix and how sparse the representation really is.

You are defining a very small matrix that is not very sparse at all.

Here I create a reasonably sparse matrix using SparseArray.

enter image description here

Then I measure ByteCount with and without Normal.

The plot shows how for large matrix there is a significant advantage on storing a SparseArray.

ListPlot[
    Transpose@Table[
        Map[
            {n, ByteCount[#]}&
            , { Normal[#], # }& @ SparseArray[{{1,1}->9, {i_, j_}/;(i==j-1) -> 1}, {n,n}, 0]
        ]
        ,{n, PowerRange[1,2^14, 2]}
    ]
    , ScalingFunctions -> {"Log", "Log"}
    , PlotLegends ->{"Normal", "Sparse"}
    , FrameLabel -> {"Size", "ByteCount"}
    , PlotTheme  -> "Scientific"
    , Joined -> True
    , InterpolationOrder->2
]

enter image description here

Show[
    %,
    Plot[
        {8 x^2, 48 x, 160, 1100}
        , {x,1,2^14}
        , ScalingFunctions -> {"Log", "Log"}
        , PlotStyle-> Directive[Gray, Opacity[0.25]]
    ]
    , PlotRange->All
]

enter image description here

From the documentation:

Sparse arrays are typically used for efficient linear algebra where most of the entries are zero and for graph adjacency matrices.

A sparse array stores only the positions where there are nonzero values, but represents the full array

Therefore, SparseArray is not only justified by the storage. Further advantages come on more efficient linear algebra operations over SparseArrays.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.