Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most efficient matrix representation in C++?

I hope that this question is not OT.

I'm implementing a VLAD encoder using the VLFeat implementation and SIFT descriptors from different implementations to compare them (OpenCV, VLFeat, OpenSIFT).

This is supposed to be an high performance application in C++ (I know that SIFT is very inefficient, I'm implementing a parallel version of it).

Now, VLAD wants as input the pointer to a set of contiguous descriptors (math vectors). The point is that usually this SIFT descriptors are represented as a matrix, so it's easier to manage them.

So supposing that we have a matrix of 3 descriptors in 3 dimensions (I'm using these numbers for sake of simplicity, actually it's thousands of descriptors in 128 dimensions):

1 2 3
4 5 6
7 8 9

I need to do feed vl_vlad_encode with the pointer to:

1 2 3 4 5 6 7 8 9

An straightforward solution is saving descriptors in a cv::Mat m object and then pass m.data to vl_vlad_encode.

However I don't know if cv::Mat is an efficient matrix representation. For example, Eigen::Matrix is an alternative (I think it's easy to obtain the representation above using this object), but I don't know which implementation is faster/more efficient or if there is any other reason because I should prefer one instead of the other.

Another possible alternative is using std::vector<std::vector<float>> v, but I don't know if using v.data() I would obtain the representation above instead of: 1 2 3 *something* 4 5 6 *something* 7 8 9

Obviously *something* would mess up vl_vlad_encode.

Any other suggestion is more than welcome!

like image 271
justHelloWorld Avatar asked Dec 14 '16 11:12

justHelloWorld


2 Answers

Unless you do some weird stuff (see here for details), data in a Mat are guaranteed to be continuous. You can think of a Mat as a lightweight wrapper over a float* (or other types) that allows easier access to the data. So it's as efficient as a pointer, but with a few nice-to-have abstractions.

If you need to efficiently load/save from/to file, you can save the Mat in binary format using matread and matwrite.

like image 85
Miki Avatar answered Sep 28 '22 06:09

Miki


std::vector<std::vector<float>> v is not going to perform very well without some effort, since the memory will not be contiguous.

Once you have your memory contiguous, be it float[], float[][] or std::array/vector, how well it will perform will depend on how you iterate over your matrix. If it's random access, then it makes little difference; if you're iterating all columns per for then it's better to have your data grouped by column rather than row.

like image 27
UKMonkey Avatar answered Sep 28 '22 06:09

UKMonkey