Solved Transpose 2d vector

December 8, 2011 at 10:48:50
Specs: Windows 7
I am trying to extract data from multiple files into one output file.
At the moment I am able to extract the columns I want into a vector in a vector:
vector< vector<double> > out;   //2D vector
ofstream myfile ("example.txt");    //outputfile

//the data contained in data[n][6] is put into the vector called 'out'.
for(int i = 1; i < iNumberOfFiles+1 ; i++) {
	vector<double> row;	
	for (int n = 79; n < data.size(); n++) {
		row.push_back(data[n][6]);
	}  
	out.push_back(row);
}

//print the data in myfile
for(int i=0;i<out.size(); i++) {
	for (int j=0;j<out[i].size(); j++)
		myfile << out[i][j] << " ";
	myfile << endl; 
}
/*
Now here comes my problem, the data is put out as
a1	a2	a3	….	aN
b1	b2	b3	….	bN
.	.	.	….	...
x1	x2	x3	…	xN

but I need the data in the following form:
a1	b1	.	x1
a2	b2	.	x2
.	.	.	.
aN	bN	.	xN
*/

//I though the data could be transposed like  a 'normal' 2d array
vector< vector<double> > outtrans;   //the 'transposed' vector
for(int i=0;i<out.size(); i++) {   
	for (int j=0;j<out[i].size(); j++){
	        outtrans[j][i] = out [i][j];
	}
}
/* this is not working properly however, when running this code, it (windows) says
file.exe is not functioning properly */

Does anyone have tips of how to transpose my vector properly (vector< vector<double> > out)?


See More: Transpose 2d vector

Report •

#1
December 8, 2011 at 14:12:02
Obvious question: why not just transpose the output?
//Assumed: Each vector<double> has the same number of elements
for (int i = 0; i < out[0].size(); ++i) { 
  for (int j = 0; j < out.size(); ++j)
    myfile << out[j][i] << '\t';
  myfile << '\n';
}

How To Ask Questions The Smart Way


Report •

#2
December 9, 2011 at 00:39:06
The number of rows and columns is mostly different from each other. When I tried transposing the output, the program would get stuck at the point where the printing should take place.

It was a memory allocation problem (http://www.daniweb.com/software-development/cpp/threads/399192/1711596#post1711596):

//allocate memory properly for the new vector before trying to access it
vector< vector<double> > outtrans(out[0].size(), vector<double>(out.size()));

        for(int i=0;i<out.size(); i++) {  
          for (int j=0;j<out[i].size(); j++){
            outtrans[j][i] = out [i][j];
                   }
          }


Report •

#3
December 9, 2011 at 12:00:55
✔ Best Answer
Just a warning: If out[0] is smaller than any other vector in your vector<vector<double> >, you're still going to have memory allocation problems. I bring this up because you mention the rows / columns are of different length. Also, duplicating data just for display is inefficient.
//Use iterators to mark current transposed row
vector<vector<double>::iterator> itVect;
for (vector<vector<double> >::iterator it = out.begin(); it < out.end(); ++it)
  itVect.push_back(it->begin());

//Loop though itVect, incrementing the iterators as we go until everything
//hits the end of their respective vector. 
bool moreData;
do {
  moreData = false;
  for (int i = 0; i < itVect.size(); ++i) {
    if (itVect[i] < out[i].end()) {
      myfile << *itVect[i];
      moreData = (++itVect[i] < out[i].end()) || moreData;
    }
    myfile << '\t';
  }
  myfile << '\n';
} while (moreData);

How To Ask Questions The Smart Way


Report •

Related Solutions

#4
December 12, 2011 at 09:43:53
Many thanks for your reply, it is very educative. I noticed I was duplicating data, but not sure how to deal with this in a more efficient way (am a beginner indeed).

In the alternative code you posted, there two things I don't understand well:

  itVect.push_back(it->begin());

Especially the
it->begin()
bit I am unsure how it exactly works. I have the feeling during the iteration, the new data gets put at the beginning of itVect (assuming begin() belongs to the beginning of itVect)? Is this a shorter notation for something else?

The second question is about this bit:

moreData = (++itVect[i] < out[i].end()) || moreData;

This line then does:
moreData = (true/false)||(false); (which will result in true if the first bit is true, so that the loop will keep being executed).
Now my question what is the meaning of the two "++" in front of itVect[i]
++itVect[i] < out[i].end())

I suppose I could actually test this last question myself easily by playing a bit with this...*cough* But I hope you don't mind to answer my first question :)

Report •

#5
December 14, 2011 at 08:45:47
Before we go on, I'm going to say something that probably doesn't need to be said, but I will anyways. We have talked about how vector<vector<double> > is 2D:
vector<vector<double> >
  |
  +--------------------> double  double  double  double  double
                         double  double  double  double  double
                         double  double  double  double  double

It's not. It's a 1D vector containing 1D vectors containing doubles:
vector<vector<double> >
  |
  +-- vector<double> --> double  double  double  double  double
  +-- vector<double> --> double  double  double  double  double
  +-- vector<double> --> double  double  double  double  double

This is relevant because most of the confusion can be attributed to me working against the inner vectors, and not the outer vector. This is also important when iterating though all of the elements. The code you posted in the OP was going to each vector, and grabbing each double in that vector before moving onto the next vector. What you want to do is grab the first double in each vector, then move onto the second double in each vector.

I should have probably just used a for loop nested in another for loop (like the original example I gave), but I got it in my head to use iterators, so that's what I did.

So let's talk about iterators. They're basically small objects that act as pointers. You can increment them (operator++) and you can typically dereference them (operator*). vector.begin() gives you a random access iterator pointing to the first element, so you can move around its data as needed. vector.end() points to just past the last element. This is why I test to make sure the iterator is less than (and not less than or equal to) that vector's end().

Especially the

it->begin()
bit I am unsure how it exactly works.
Remember how I said vector<vector<double> > is a vector containing vectors? I'm walking the main vector<vector<double> >, and grabbing each vector<double>'s beginning iterator. These iterators point to the actual doubles.

Now my question what is the meaning of the two "++" in front of itVect[i]

++itVect[i] < out[i].end())
It increments the iterator at itVect[i] by one. It's the same concept as i++, but slightly different. With i++, i is incremented by one, and you get the value of i before it was incremented. With ++i, i is incremented by one and you get the value of i after it was incremented. i++ sometimes requires a temporary copy of the variable to be made. When this happens, i++ will be slower than ++i. You're taught i++ because it conforms to the rest of the language, where you have
<variable><changes to variable> (i.e. i = i + 1).

How To Ask Questions The Smart Way


Report •

#6
January 5, 2012 at 06:59:07
This reply is WELL late, but I just wanted to say I greatly appreciate your help by explaining the vector background and answering my questions.
Happy New Years to all too =)

Report •

Ask Question