Averaging elements of a 2D vector in C++

Hello, my code is returning only the last element calculated inside the loops.
I am "binning" (resize averaging the neighbors elements) a matrix 4x4 into a 2x2. I am taking the average of values in a square, for instance 1.0 +2.0 +5.0+ 6.0 divided by four, this is the [0][0] elements of the new matrix. Below the matrix called "a" from .txt file.
1
2
3
4
1.0 2.0 3.0 4.0
5.0 6.0 7.0 8.0
9.0 10.0 11.0 12.0
13.0 14.0 15.0 16.0 


The expected result 2x2 "matrix_binned":
1
2
3.5 5.5
11.5 13.5


My code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    std::vector<std::vector<float>> matrix_binned(2, std::vector<float>(2, 0));
    int n, m, i, j;
    for (n = 0; n < 4; n+=2) {
        for (m = 0; m < 4; m+=2) {

            for (i = 0; i < 2; ++i) {
                for (j = 0; j < 2; ++j) {

                    matrix_binned[i][j] = (a[n][m] + a[n][m + 1] + a[n + 1][m] + a[n + 1][m + 1]) / 4;
                    
                 }
            }  
        }
        
    }  


When printed, all the elements shown are 13.5.
Last edited on
You want to map the elements of the 4x4 array to the 2x2 array like this:

  0       1
0 0,0 1,0 2,0 3,0
  0,1 1,1 2,1 3,1
1 0,2 1,2 2,2 3,2
  0,3 1,3 2,3 3,3

You just need a double loop (not a quadruple loop!).

Note that I've put the y (row) coordinate first so that it matches how the initializer looks. It may seem a little weird but in C++ matrices are (IMO at least) indexed [row][col] or [y][x]. (IIRC you were doing it the other way around in the last program.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <iomanip>
#include <vector>

using InnerVec = std::vector<float>;
using Matrix = std::vector<InnerVec>;

int main()
{
    Matrix a
    {
        {  1.0,  2.0,  3.0,  4.0 },
        {  5.0,  6.0,  7.0,  8.0 },
        {  9.0, 10.0, 11.0, 12.0 },
        { 13.0, 14.0, 15.0, 16.0 }
    };

    Matrix binned(2, InnerVec(2));
    for (int y = 0; y < 2; ++y)
        for (int x = 0; x < 2; ++x)
            binned[y][x] = (a[y*2  ][x*2  ]
                          + a[y*2  ][x*2+1]
                          + a[y*2+1][x*2  ]
                          + a[y*2+1][x*2+1]) / 4.0;

    std::cout << std::fixed << std::setprecision(2);
    for (int y = 0; y < 2; ++y)
    {
        for (int x = 0; x < 2; ++x)
            std::cout << std::setw(6) << binned[y][x] << ' ';
        std::cout << '\n';
    }
}

Hello dutch! it worked perfectly.

I also test it with a 1024x1024 .txt file, doing some adjustments, and was perfect. I am now analyzing my code and yours comparatively, but anyway I think your code is less expensive certainty.

Yes, I was doing [y][x] in the last program, I thought that behavior was only to write & read .txt and .csv, but not when writing or reading a matrix. Very important to know.

Thank you so much dutch.

Topic archived. No new replies allowed.