1

This if my first post, I hope I'll meet the standards...

I'm translating into c++ (at which I'm quite new) a program originally written in MATLAB for reasons of efficiency. The piece of code I am actually working on resumes accesses to various indexes of a vector (matrix) in one step. For example, if M1 is a matrix of size, let's say, 10x15, the program would define a new one as follows:

idxs1 = [1 2 3];
idxs2 = [1 2 3 4 5];
M2 = M1 (idxs1 , idxs2);

resulting M2 as a matrix of size 3x5. Now, I guess what MATLAB actually does is access one by one the various places of M1 given by the indexes and then construct M2 by rearranging the many contents acquired, all very efficiently.

My question is, how can I reproduce such mechanism in c++? As far as I know there is no direct way to access in a row various indexes of an array, and the for loop I'm using seems rather cumbersome. Maybe there's some intelligent way to do it without demanding 'too much' processor time? Also, for the sake of educational purposes, I would be grateful if someone could explain what MATLAB actually does when such operation is performed.

Thanks in advance and sorry for the eventual inconveniences!

P.S: Just in case it adds anything to the question, I'm working with MEX files to link both languages. P.S2: By the way, I found some related questions but regarding other languages:

Community
  • 1
  • 1
  • You're going to be very hard pressed to improve on the efficiency of Matlab. – 1201ProgramAlarm Jan 04 '16 at 06:24
  • Why would you think it would be easy to beat Matlab in terms of efficiency? Matlab mainly uses [BLAS](http://www.netlib.org/blas/) and [LAPACK](http://www.netlib.org/lapack/) for matrix operations. These libraries were originally written in fortran. You can use these functions by using some [c wrappers](http://se.mathworks.com/help/matlab/matlab_external/calling-lapack-and-blas-functions-from-mex-files.html). Matlab also uses a matrix type called mxArray. It is possible to use other matrix libraries I suppose, but you should avoid writing all yourself unless you are a bored math genius. – patrik Jan 04 '16 at 09:10
  • C++ matrix library with [non-contiguous submatrix views](http://arma.sourceforge.net/docs.html#submat). also has a MEX interface – hbrerkere Jan 04 '16 at 12:06
  • Thanks a lot for the helpful answers. I expressed myself incorrectly suggesting I was trying to beat MATLAB =) What I'm actually doing is translating to C++ in order to jump to CUDA afterwards. That said, it turns out my program actually runs faster than MATLAB, but only if the size of the system is "small enough", MATLAB beating my implementation for bigger systems (i.e, matrixes), and, moreover, taking roughly the same amount of time no matter the size. That is an achievement due to smart coding (not by me) which I hope to replicate via Armadillo. Thanks for the answers! =) – Alejo Alberti Jan 07 '16 at 01:57

3 Answers3

2

"Armadillo is a high quality C++ linear algebra library, aiming towards a good balance between speed and ease of use

Useful for algorithm development directly in C++, or quick conversion of research code into production environments; the syntax (API) is deliberately similar to Matlab"

Link: http://arma.sourceforge.net/

Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64
0

Math program data structures can be some of the most elaborate out there. I can't even figure out what the 3rd line of your example actually does, so I can't even guess how MATLAB implements anything.

What I can tell you is, that one line of MATLAB is almost certainly hiding a ton of operations. If you want to recreate it you just need to make a utility function with a couple of for-loops that copy over all the correct indices one-by-one. Ultimately, this can't be too much different than one MATLAB does.

If you have a ton of matrix operations you need to support and you're on a large project, you might want to look into finding a C++ matrixes library. I don't have one to recommend, but Boost is a popular C++ library for many purposes including matrixes. (You can also make your own data structure, but not recommended for a novice.)

Paul K
  • 154
  • 6
  • Great advice, and definately writing a data structure is out of my league for the time being. Actually, that "C++ matrixes library" is the suggestion by @Severin, patrik and hbrerkere, so I think you're all aiming towards the same thing. Despite I haven't got into Boost documentation I think I'll go for Armadillo due to the syntax similarities with MATLAB (and for speed issues as well -http://stackoverflow.com/questions/14414906/compare-blitz-armadillo-boostmultiarray-, though the comparisons aren't very thoroughly performed). Thanks for replying! – Alejo Alberti Jan 07 '16 at 02:18
0

What MATLAB exactly does is left unspecified, and might very well differ from case to case depending on the indices, and even for a given set of indices it could differ from machine to machine. So let's not speculate.

In particular, it's left unspecified whether MATLAB physically copies M1. Such a copy can be faked, which saves time. The technique is known as "copy on write".

In C++, this would be possible as well, but harder. Furthermore, none of the existing container classes supports it.

If you're going to copy the elements, the CPU won't be the bottleneck. Instead, the memory bus will limit you. This is particularly the case when the indices aren't contiguous. For a 3x5 matrix, the time will be dominated by overhead - contiguity doesn't matter yet.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Thanks for your answer, and completely agree with the "no speculation" premise. Just thought there could be some standard tweak I ignored. What my program needs is to take in one step (avoiding an explicit `for`) a piece of a matrix, not necessarily copying it (something like a "pointer to many memory spaces" -which obviously doesn't exist as such- would do). Great suggestion about the bus! Good thing is the indices are contiguous. And the matrixes are of size ~150000 x 100, so better not to copy, right? =) – Alejo Alberti Jan 07 '16 at 02:06