1

I dug into the boost ublas code and found out the ublas implementation for memory allocation in compressed_matrix is not as standard as in CSC or CSR.

There is one line that cause the trouble, namely, non_zeros = (std::max) (non_zeros, (std::min) (size1_,size2_)); in the private restrict_capactiy method.

Does that mean if I create a sparse matrix the number of nonzero allocated in boost ublas will always be greater than min(nrow, ncol)?

The following code I used to demonstrate this problem. The output will has zeros in the unused part of the vector allocated in compressed_matrix.

typedef boost::numeric::ublas::compressed_matrix<double, boost::numeric::ublas::column_major,0,std::vector<std::size_t>, std::vector<double> > Matrix;
long nrow = 5;
long ncol = 4;
long nnz = 2;

Matrix m(nrow, ncol, nnz);
cout<<"setting"<<endl;
m(1,2) = 1.1;
m(2,2) = 2.1;
    for(int i=0;i<m.index1_data().size();i++)
{
    cout<<"ind1 -"<<i<<" "<<m.index1_data()[i]<<endl;
}

for(int i=0;i<m.index2_data().size();i++)
{
    cout<<"ind2 -"<<i<<" "<<m.index2_data()[i]<<endl;
}

for(int i=0;i<m.value_data().size();i++)
{
    cout<<"val  -"<<i<<" "<<m.value_data()[i]<<endl;
}

1 Answers1

0

Perhaps it is a performance-design choice with certain use cases in mind.

The idea is that when filling the compressed_matrix one might try to minimize reallocations of the arrays that maintains the index/values arrays. If one starts from 0 allocated space, it will quickly to speculativelly reallocate once in a while (e.g. reserving twice the space each time the allocated space is exceeded, like std::vector does).

Since the idea is to kill the $N^2$ scaling of the dense matrix. A good guess is that in an sparse matrix you will use more or less $N$ elements out of the $N^2$. If you use more than $N$ then reallocation will happen at some point but not as many times. But then you will probably be in the case when it is better to switch to a dense matrix anyway.

What is a little more surprising is that it overwrites the passed value. But still, the above applies.

alfC
  • 14,261
  • 4
  • 67
  • 118