2

I have a 2D-matrix whose column size increases after every iteration but the row size remains fixed. For each iteration, a function returns a matrix which I would like to stack horizontally. Following is the code I tried but I think I am doing something wrong in the big_mat[ii].insert part. But I looked around and found codes for vertical stacking where you can start from big_mat.end() and perform insert. But I want the row size to remain fixed. Can you please help me with this ? Also the maximum final size would be of the order 1,000,000 times 5,000.

std::vector<std::vector<float> > big_mat;
big_mat.reserve(fixed_row_dim);

std::vector<std::vector<float> > small_mat;

for (some condition){
    // small_mat is always fixed_row_dim x some_dim
    small_mat = GetMat(params,fixed_row_dim);   
    for (int ii = 0; ii < fixed_row_dim; ii++){
        big_mat[ii].insert(big_mat[ii].end(),small_mat[ii].begin(),small_mat[ii].end());
    }
}
sm176357
  • 96
  • 13
  • "but I think I am doing something wrong": What do you think is wrong and why? – JohnB Jan 17 '16 at 11:37
  • What is the problem with your code? And do you realise 1,000,000 * 5,000 * sizeof(float) is around 20GB (around because bytes use 1024 instead of 1000 for Kilo) – FrankM Jan 17 '16 at 11:40
  • @JohnB I intended to extend of a solution provided [here](http://stackoverflow.com/questions/201718/concatenating-two-stl-vectors) for two dimensions. But the big_mat[ii].insert might not be the proper way. So I guess I am wrong there. @ FrankM Yes I am aware of that. The code will be run on a cluster. So for each job id, the generated data will linearly decrease in size as the first batch would compare similarities between 0 to N-1 and then the next one from 1 to N-1 and likewise. I am currently testing on one pair. – sm176357 Jan 17 '16 at 11:41
  • and the problem is? it's quite funny to read a description of the problem which sounds like "Abracadabra I do not know what I want to do but definitely it is not the thing I have done here" :D – Dominik Jan 17 '16 at 12:46
  • The following snippet is not working. big_mat[ii].insert is not working and throwing up seg fault. I even tried element wise [push_back](http://stackoverflow.com/questions/27241177/inserting-elements-into-2d-vector) but didnt work (`big_mat[ii].push_back(*(it))') . – sm176357 Jan 17 '16 at 12:57
  • @Dominik sorry but can you help ? – sm176357 Jan 17 '16 at 13:04
  • I do not know yet. first help us understand what is going on. 1) what do you mean by "column size incrase after every iteration"? elements of your columns are getting bigger, or number of elements increase or what? 2) what iteration?! 3) what function returns a matrix which u want to stack horizontally? 4) stack horizontaly, ok but how? do you want to concatenate elements from each row? – Dominik Jan 17 '16 at 13:08
  • @Dominik Lets say I have a fixed number of row 500. At the end of first iteration I get a 500 by 600 mat. Next time I get 500 by 700. I intend the big_mat to be 500 by 600 after first and 500 by 1300 after second iteration respectively. – sm176357 Jan 17 '16 at 13:11
  • ok. so you have `std::vector> big_mat` at the beginning and then you are going to add some elements to each row. so the question is about how to add elements to your vector `std::vector`, am I right? – Dominik Jan 17 '16 at 13:17
  • "For each iteration, a function returns a matrix which I would like to stack horizontally." yes, that is what I meant. – sm176357 Jan 17 '16 at 13:27
  • @baptu88 check out my answer please and tell me if it fixed your issue. Cheers – Dominik Jan 17 '16 at 13:56

1 Answers1

2

I have tried to compile your code, with necessary editions of course and it is working just fine. so what is the problem and what kind of error do you get?

int main() {
  std::vector<std::vector<float> > big_mat;
  big_mat.reserve(5);

  std::vector<std::vector<float> > small_mat;

  for (int i = 0; i < 10; i++){
    // small_mat is always fixed_row_dim x some_dim
    std::vector<float> example = { 1, 2, 3, 4, 5 };
    std::vector<std::vector<float>> small_mat;

    for (int ii = 0; ii < 5; ii++) {
        small_mat.push_back(example);
    }
    for (int ii = 0; ii < 5; ii++){
        big_mat[ii].insert(big_mat[ii].end(), small_mat[ii].begin(), small_mat[ii].end());
    }
  }
}

however I get "debug assertion failed" error while trying to run that code in visual studio 2013. the reason was that big_mat was empty- had size smaller than the number of iterations. changing the initialization of big_mat from:

 big_mat.reserve(5);

to:

  for (int ii = 0; ii < 5; ii++) {
    big_mat.push_back(*(new std::vector<float>()));
  }

fixed the issue. I think that this is the problem with your code. I will try to get some information about std::vector::reserve function and explain it to you in next few minutes.

Edit: as @Zereges pointed out. Proposed way of initialization of two dimensional vector will cause memory leaks, safe and more sexy way to achive this is:

std::vector<std::vector<float> > big_mat { 5, std::vector<float>{0f} }

Explanation: as you can read in the documentation, the reserve function

Requests that the vector capacity be at least enough to contain n elements.

just guarantee that the vector of given size will fit in the memory without reallocation required. It does not initialize anything, so your big_mat vector of vectors was empty and you have tried to iterate over it in your loops.

Dominik
  • 331
  • 1
  • 4
  • 12
  • 1
    `big_mat.push_back(*(new std::vector()));` causes memory leaks. Use `std::vector > big_mat { 5, std::vector{0f} }` to initialize vector with `0f` – Zereges Jan 17 '16 at 14:00
  • Zerges thank you for pointing that out and giving proper alternative. @GeorgeNetu thanks : ) – Dominik Jan 17 '16 at 14:26