boost compressed matrix storage
The boost ublas::compressed_matrix
should only allocate space for non-zero elements. But in the below example, I am getting strange results.
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/io.hpp>
using namespace std;
using namespace boost::numeric::ublas;
int main () {
{
compressed_matrix<double,row_major> m (4, 4, 2*2);
cout << sizeof(m) << "\n"; // prints 56
cout << m << std::endl;
}
{
matrix<double> m (4, 4);
cout << sizeof(m) << "\n"; // prints 20
cout << m << std::endl;
}
return 0;
}
Why is ublas::matix
taking only 20
bytes for 4x4 matrix
(instead of 8*4*4=128
bytes) whereas ublas::compressed_matrix
with 2*2=4
non-zero elements is taking 56
bytes (instead of 4*8=32
bytes)?
I was also confused how do I specify location of the non-zero elements in ublas::compressed_matrix
. What happens if I try to store more tha开发者_StackOverflow中文版n the number of non-zero elements set in constructor?
Please help clarify.
sizeof() is a compile time operator that only looks at the direct size of the object and not any allocations that the object might make at runtime. For example:
class SizeTest
{
public:
char* m_pData;
SizeTest()
{
m_pData = new char[1000];
}
};
int main (void)
{
SizeTest Test;
cout << sizeof(Test) << "\n"; //Probably prints 4 depending on your system
return 0;
}
sizeof()
doesn't know the memory allocation at run-time. To fully understand the question, you need to know the implementation of ublas::matix
and ublas::compressed_matrix
, both of them have an underlying storage array (ublas::::unbounded_array
by default, and you can choose others by specifying the template parameter). Unlike ublas::matix
, ublas::compressed_matrix
only stores the non-zero elements of the matrix.
I was also confused how do I specify location of the non-zero elements in ublas::compressed_matrix.
use the iterator.
What happens if I try to store more than the number of non-zero elements set in constructor?
I don't understand how you store more than the number of non-zero elements set in constructor, if you mean the third parameter, it's just the pre-allocated size of the underlying storage array.
For example:
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/storage.hpp>
namespace ublas = boost::numeric::ublas;
int main()
{
ublas::compressed_matrix<double> m(4, 4, 2*2);
m(1,2) = 3.5;
std::cout << m.value_data().size() << '\n';
typedef ublas::compressed_matrix<double>::iterator1 it1_t;
typedef ublas::compressed_matrix<double>::iterator2 it2_t;
for (it1_t it1 = m.begin1(); it1 != m.end1(); it1++)
{
for (it2_t it2 = it1.begin(); it2 != it1.end(); it2++)
{
std::cout << "(" << it2.index1() << "," << it2.index2() << ") = ";
std::cout << *it2 << std::endl;
}
}
{
ublas::matrix<double> m(4,4);
std::cout << m.data().size() << '\n';
}
{
ublas::compressed_matrix<double> m(4, 4, 5*5);
std::cout << m.value_data().size() << '\n';
}
}
The memory is allocated when calling compressed_matrix constructor when given the dimension information and number of nonzeros. And for the matrix type, the memory is probably be dynamic allocated later when you insert elements in the matrix.
精彩评论