Finding maximum value in each column of a 2-D vector
An answer to this question on Stack Overflow.
Question
I have created a 2-D vector called cosmic_ray_events. It has 1234487 rows and 9 columns. I want to find the max value out for each column from all the rows. I keep getting a segmentation fault whenever I try to run my code and I am note sure why. I have also created the cosmic_ray_events vector by loading in values from a dat file. Any advice is appreciated.
vector<vector<double> > cosmic_ray_events(total_cosmic_ray_events, vector<double>(9,0));
ifstream cosmic_ray_data("events_comp-h4a_10.00-10000.00PeV_zen37.00.dat", ios::in);
while(cosmic_ray_data.good())
{
for(int i = 0; i < 1233487; i++) //1233487 is the number of rows in the dat file
{
for(int j = 0; j < cosmic_columns; j++)
{
cosmic_ray_data >> cosmic_ray_events[i][j]; //reading in data for 2-D vector
}
}
}
double max[9];
std::vector<double> find_max;
for(int i = 0; i < 1234487; i++)
{
for(int j = 0; j < 9; j++)
{
find_max.push_back(cosmic_ray_events[i][j]);
max[j] = *max_element(find_max.begin(), find_max.end());
find_max.clear();
}
}
Answer
Since you're using std::vector, you can do yourself a favor and do a range check on every look-up. This will prevent the segfault and return an intelligible error message instead. Doing that would look like this:
vector<vector<double> > cosmic_ray_events(total_cosmic_ray_events, vector<double>(9,0));
ifstream cosmic_ray_data("events_comp-h4a_10.00-10000.00PeV_zen37.00.dat", ios::in);
while(cosmic_ray_data.good()){
for(int i = 0; i < 1233487; i++){ //1233487 is the number of rows in the dat file
for(int j = 0; j < cosmic_columns; j++){
cosmic_ray_data >> cosmic_ray_events.at(i).at(j); //reading in data for 2-D vector
}
}
}
double max[9];
std::vector<double> find_max;
for(int i = 0; i < 1234487; i++){
for(int j = 0; j < 9; j++){
find_max.push_back(cosmic_ray_events.at(i).at(j));
max[j] = *max_element(find_max.begin(), find_max.end());
find_max.clear();
}
}
Also, note that the last set of loops introduces a single element into find_max, finds the maximum element of find_max (the element you just pushed in), and saves that to max[j].
I don't think your code does what you think it does. You probably want:
std::vector<double> max_vals(9,-std::numeric_limits<double>::infinity());
for(int i = 0; i < 1234487; i++){
for(int j = 0; j < 9; j++){
max_vals.at(j) = std::max(max_vals.at(j),cosmic_ray_events.at(i).at(j));
}
}