0

I am new to vector programming in C++. I want to initialize 2D matrix of unknown size so i came to vector side. I have two files 1) .h and 2).cpp. In .h file i initialized the vector like this

vector<vector<double> > vector_stor;

Then in .cpp after getting the size of each dimension from another source i re-sized the vector like this

size_X=5; //assumption
size_Y=5; //assumption    
vector_stor.resize(size_X);
for(int i=0;i<size_X;i++)
vector_stor[i].resize(size_Y);

Now i want to store a data from a .mat file, initially read by matIO library, using Mat_VarRead function like this

Mat_VarReadData(vector_stor); //there are other arguments also but for demo just assume it

Mat_VarReadData take arguements in void* data and i have 2D vector. When i am doing like this its giving error

Error 1 error C2664: 'Mat_VarReadData' : cannot convert parameter from 'std::vector<_Ty>' to 'void *'

Can anyone please guide me that how i can do this? It will be very helpful for me.

Edited Part:

  matvar = Mat_VarReadInfo(mat,"data_struct");
    field=Mat_VarGetStructFieldByName(matvar,"vect_stor",0);
    int    start[2]={0,0};
    int    stride[2]={1,1};
    int    edge[2];
           edge[0]=field->dims[0];
           edge[1]=field->dims[1];
    Mat_VarReadData(mat,field,vector_stor,start,stride,edge);

where vector_stor is the variable for what i am seeking help.

Thanks

Saad Saadi
  • 1,031
  • 10
  • 26

2 Answers2

1

Check the ordering of your inputs to Mat_VarReadData. The function needs to be something like

Mat_VarReadData( ..., vector<vector<double> > mat, ... )

and you need to line up your inputs so that vector_stor lines up with that input.

If I have the function:

foo(int a, double b);

then when I call foo the first argument needs to be an int and the second a double. Same here, you need to match your input types to what your actually trying to pass.

Also check out: http://libmatio.sourcearchive.com/documentation/1.3.3/group__MAT_g1845000f4fc6252ec5ff11c4b9f0759f.html

It looks like the function is going to dump the data into a single dimensional array, rather than a vector of vectors. Try this:

std::vector<double> mat;
mat.resize(size_X*size_Y);
// call Mat_VarReadData with &mat[0] as your void*
// now you can index with 
mat[i*size_Y + j];

That assumes that the matrix is in column major form which MATLAB uses from memory. If it uses row major you'll need to index with

mat[i + j*size_X];

EDIT: If you're curious as to why &mat[0] or mat.data() (the second requires C++11, thanks for pointing it out) works is because the std::vector is guaranteed to be contiguous,see Are std::vector elements guaranteed to be contiguous?

Community
  • 1
  • 1
Cramer
  • 1,785
  • 1
  • 12
  • 20
  • Sir..thanks for the answer and actually i know these basics of functions..my question is that how i can make `vector >` compatible to `void* data`?..is there any way or not? thanks – Saad Saadi Sep 06 '13 at 03:20
  • and also Mat_VarReadData is a builting function and modification is way too difficult... – Saad Saadi Sep 06 '13 at 03:21
  • @Cramer He just call the Mat_VarReadData(void *). – jfly Sep 06 '13 at 03:21
  • @SaadSaadi If you're calling the [Mat_VarReadData](http://libmatio.sourcearchive.com/documentation/1.3.3/group__MAT_g1845000f4fc6252ec5ff11c4b9f0759f.html#g1845000f4fc6252ec5ff11c4b9f0759f), a vector of vectors isn't going to help. You need to provide a contiguous block of doubles with the rest of the parameters appropriately configured. – WhozCraig Sep 06 '13 at 03:24
  • You can't. The way most people (including MATLAB) treat multi dimensional arrays is to use a single dimension then split it up. Say you have a NxM matrix, you can make an array `double mat[N*M]` and then index it with `mat[i*N + j]` or `mat[i + j*M]` depending on if it is column major (first) or row major (second). – Cramer Sep 06 '13 at 03:25
  • **It looks like the function is going to dump the data into a single dimensional array, rather than a vector of vectors**..if i do like this `double vector_stor[5][5]`..its working properly but my aim is to make it for unknown sizes...thanks – Saad Saadi Sep 06 '13 at 03:27
  • @WhozCraig, Can i go for pointers like this..`double **vector_stor`...and then allocating memory and dimension...what u say? – Saad Saadi Sep 06 '13 at 03:29
  • @SaadSaadi That won't work, you need it in contiguous memory whereas that will put each row in a different spot – Cramer Sep 06 '13 at 03:32
  • Don't sue me when it does not work. But if you use C++11 then std::vector has a new method: data(). So this might work: Mat_VarReadData(vector_stor.data()); There you have your continguous memory, but if the format, which Mat_VarReadData dumps into it, is correct.... Try it and tell us. :-) – Greenflow Sep 06 '13 at 03:38
  • @SaadSaadi No. you can't. Thats not a two-dimmensional array. its a pointer array of individual addresses. Your "this works" example is honestly the best evidence you have that, given an X-by-Y matrix, they *expect* a *contiguous* block of (X*Y) doubles. You can do that with a single `std::vector` without a problem. Just work out the math. (and read the documentation, of course). – WhozCraig Sep 06 '13 at 03:43
  • @Cramer...i checked your edited post and applied on my code but its giving the same error...now i am thinking to do something diff...can i make a 2D array from `vector >` of the same size as of vector and also then saving back into the vector from array..? – Saad Saadi Sep 06 '13 at 03:45
  • @SaadSaadi `vector >` is not going to work. Could you give us your full call to `Mat_VarReadData`? – Cramer Sep 06 '13 at 05:44
  • You didn't do what I wrote. Try `Mat_VarReadData(mat,field,&vector_stor[0],start,stride,edge);` with `vector_stor` as a SINGLE DIMENSIONAL vector. Like I wrote in the answer. – Cramer Sep 06 '13 at 06:12
  • @Cramer..lets for the demo purpose..so that i can be sure about the result..if i want to print the &mat[0][0]...how i can do? i called like yours idea and no error but want to check it – Saad Saadi Sep 06 '13 at 06:51
  • Note it's not &mat[0][0], it's &mat[0], you need to pay attention. &mat[0] is an address, there's no point printing it it's just some random number. I think you need to have a crack at some simpler problems to get more of the fundamentals. – Cramer Sep 06 '13 at 09:00
  • @Cramer or `mat.data()`, concur with everything else. – WhozCraig Sep 06 '13 at 15:04
0

As others have already pointed out, you won't be able to pass neither vector <vector<double> > nor vector<double> directly to Mat_VarReadData in the form of void*, there's simply no safe way to do that. The best you can do is first to retrieve the data into some raw array, then convert it accordingly to the container you like.

I'm not familiar to MatIO, but I'll try to point you to the right direction. I took a look at the documentation for Mat_VarReadData. Not very helpful I must admit, but at any rate it states that any data can only be read once you have retrieved the information about the corresponding variable. That can be done using the function Mat_VarReadInfo. This function returns a matvar_t, which essentialy is a descriptor for variables. It seems to me, that matvar_t contains all the information you need to allocate data dynamically, that is, through the use of new[]. More precisely, matvar_t::data_size should hold exactly how many bytes are needed to store the data of a given variable. I think that's more or less what you need to do:

warning, not tested

matvar_t* varInfo = Mat_VarReadInfo(matFileDescriptor, varName)
char* data = new char[varInfo->data_size];
Mat_VarReadData(matFileDescriptor, varInfo, (void*)(data), start, stride, edge);

I'll leave it to you to figure out what start, stride and edge actually stand for.

After you have the data read into the array data, you will have to convert it to the appropriate arithmetic type, probably double, but I can't be sure. Only then you will be able to fit them into a vector<double>. On this part I unfortunately can't help you, because it gets too deep into MatIO.

I understand you are struggling with basics c/c++ and also with MatIO. That's no simple library to be used by someone just starting out coding in c/c++, so I would strongly advise you to first carefuly read any documentations you have available on MatIO before trying any progress with your project. Some reading on basics c/c++ would also be very helpful.

Community
  • 1
  • 1
brunocodutra
  • 2,329
  • 17
  • 23
  • @brunocodutra...Thanks for the explanation....Regarding matIO i already developed the whole program but now i want to make user friendly by not fixing the size of the array in which it will be stored so that's why i was planning to use vector...my .mat file inlcude 1 struct which in turn includes 14 variables of diff types and sizez...by getting the data size from matlab i did it but now i want to make it without the usage of matlab....now looking to do it for unknown sizes..:) – Saad Saadi Sep 06 '13 at 05:36