Introduction to Armadillo#

Armadillo is an efficient linear algebra library for C++, that balances speed and ease of use. We recommend using this library for numerical linear algebra computations in this course.

We’ll cover some of the very basics of Armadillo here to get you started with the library. A complete overview of the available classes and functions, along with usage examples, can be found in the Armadillo code documentation.

Building code with Armadillo#

We must make sure to include the header file for Armadillo, which amounts to adding #include <armadillo> at the top of a header or source file.

Note

In case you are having trouble compiling a file using armadillo, you can make sure you are using a compatible C++ standard version, which would be C++14 or later. This can be done by supplying the compiler flag --std=c++14 during compilation.

Linking code with Armadillo#

To link to Armadillo, we must add the compiler flag -larmadillo during linking.

Vectors#

Armadillo provides a useful vector class arma::vec that can be used to replace arrays in numerical computations. Assume n is a positive integer.

Declaring and filling vectors#

arma::vec x(n); // Initialize vector but don't fill it
arma::vec y(n).fill(2.); // Declare and fill a vector with 2's
arma::vec z(n).randu(); // Declare and fill a vector with random values from a uniform distribution
arma::vec u("0.0 0.1 0.2"); // Declare and fill a vector with the values 0.1, 0.2 and 0.3

Accessing and assigning elements in a vector#

We can access an element i from a vector x by

double x_i = x(i); // Extract element i of x and assign it to x_i.

We can assign a new value to element i in the vector x using

x(i) = some_new_value;

Matrices#

Assume that n and m are positive integers.

Declaring and filling matrices#

Creating matrices with Armadillo is easy. Here’s a couple examples:

arma::mat A(n, m); // Initialize matrix but don't fill
arma::mat B(n, m).fill(0.); // Declare and fill a matrix with zeros
arma::mat C(n, m).randn(); // Declare and fill a matrix with random values from the normal distribution
arma::mat D("0.0 0.1 0.2 ; 1.0 1.1 1.2 ; 2.0 2.1 2.2"); // Declare and fill a 3x3 matrix with the listed values (note the semicolons)

Accessing elements in a matrix#

Access of elements in an Armadillo matrix is done as follows:

double A_ij = A(i,j); // Assign element (i,j) of the matrix A to A_ij

Extracting a column of a matrix#

Armadillo provides a simple way to extract entire columns of a matrix:

arma::vec col_vec = A.col(j); // Extract column j of A and assign it to col_vec

Read matrix columns in a given order#

A particular task that may be useful in this course is to read the columns of a matrix in a specific order. Below is an example that uses arma::sort_index to find the index ordering that sorts a given vector (from low to high values), and then sorts both the vector and the columns of a matrix according to this ordering.

arma::mat A("0.0 0.1 0.2 ; 1.0 1.1 1.2 ; 2.0 2.1 2.2");
arma::vec x("20. 10. 30.");

arma::uvec x_sort_indices = arma::sort_index(x); // Get index ordering that sorts x
  
x = x(x_sort_indices); // Sort x according to ordering in x_sort_indices
A = A.cols(x_sort_indices); // Sort columns of A according to ordering in x_sort_indices

Saving and loading vectors and matrices#

Armadillo provides built-in functionality for saving and loading arma::vec and arma::mat objects to binary files. Not only does this simplify storage of results with a predictable format, but it turns out that they provide a Python module pyarma that can me used to load in these objects directly into a Python program!

If A is an arma::mat object, you can save it using

A.save(filename);

The default storage format is binary. Your filename should end with .bin. Loading the object is as simple as

B = arma::mat() // Initialize an arma::mat variable
B.load(filename) // Load content of arma::mat A stored earlier into arma::mat B

Reading a data table in text format#

The load functionality in Armadillo can also be used to load data from files not generated by Armadillo, as long as the data file has some standard format (see the Armadillo documentation for details). For instance, assume we have a text file mynumbers.dat looking like this:

0.0000e+00  0.0000e+00  0.0000e+00
0.0000e+00  1.9635e-01  3.8553e-02
0.0000e+00  3.9270e-01  1.5421e-01
0.0000e+00  5.8905e-01  3.4698e-01
0.0000e+00  7.8540e-01  6.1685e-01
1.9635e-01  0.0000e+00  1.9635e-01
1.9635e-01  1.9635e-01  2.4247e-01
1.9635e-01  3.9270e-01  3.6569e-01
1.9635e-01  5.8905e-01  5.6599e-01
1.9635e-01  7.8540e-01  8.4336e-01
3.9270e-01  0.0000e+00  3.9270e-01
3.9270e-01  1.9635e-01  4.6150e-01
3.9270e-01  3.9270e-01  6.0723e-01
3.9270e-01  5.8905e-01  8.2971e-01
3.9270e-01  7.8540e-01  1.1288e+00
5.8905e-01  0.0000e+00  5.8905e-01
5.8905e-01  1.9635e-01  6.9558e-01
5.8905e-01  3.9270e-01  8.7831e-01
5.8905e-01  5.8905e-01  1.1363e+00
5.8905e-01  7.8540e-01  1.4688e+00

To read these numbers into an Armadillo matrix, we simply do this:

arma::mat A;
A.load("mynumbers.dat", arma::raw_ascii)