# Example: Matrix¶

Let’s look at an example from your text that create a very simple matrix container as a vector-of-vectors.

We’ll write our own version of what the text does.

Listing 8 simple_matrix.cpp
#include <iostream>
#include <vector>

// a type alias -- we can now use RealVec to mean a vector of doubles

using RealVec = std::vector<double>;

// a RealMatrix is a vector of vectors of doubles

using RealMatrix = std::vector<RealVec>;

int main() {

RealMatrix M = {
{  1.0, 25.0, 0.0,  4.1},
{ -1.0,  2.0, 4.5, -3.1},
{ 10.0, -6.0, 3.2,  4.0}
};

M.push_back({ 20.0, 2.0, 0.0, 5.0});

// let's compute the trace (sum over the diagonal)

double trace = 0.0;

for (int i = 0; i < M.size(); ++i) {
trace += M[i][i];
}

std::cout << "trace = " << trace << std::endl;

// now the sum of all the off-diagonal terms

double off_diag_sum = 0.0;

for (int r = 0; r < M.size(); ++r) {
for (int c = 0; c < M[r].size(); ++c) {
if (r != c) {
off_diag_sum += M[r][c];
}
}
}

std::cout << "off-diagonal sum = " << off_diag_sum << std::endl;

}


Tip

Notice that we use some type aliases to make it easy to reuse this datatype.

• For our matrix M, M is the first row. It is a vector, and the columns in that row are all stored together in that vector. This is an example of row major ordering of the data.
• To access an element at row r and column c, we do: M[r][c]. The first indexing, M[r] gives us the vector that holds row r ‘s data. Then we just index that vector with [c] to get the position corresponding to the column we want.
• When we push_back() onto the matrix, we are adding a whole new row.
• Both of our operations involve sums over elements – we are careful to first initialize the sum to 0 before adding to it.