Stephan Gelever

Born, raised, and educated in Portland, Oregon. I am currently in Seattle employed as a Software Development Engineer for Amazon. My background is in Mathematics and Computer Science.

© 2020

Linalgcpp Basics - Vector

This post is a basic introduction to the Vector structure in linalgcpp.

linalgcpp supports the templated Vector<T>, but all the examples in this post will use the most common Vector<double>:

using Vector = linalgcpp::Vector<double>;

Construction

There are several constructors available.

The default constructor creates a Vector of zero dimension:

Vector vector;

To create a Vector of any finite dimension \(n\), we pass in the dimension as a parameter to the constructor. This will create a zero filled vector of the given dimension:

int dimension = 4;
Vector vector(dimension);

If we wish to fill the \(n\) dimension vector with some other initial value, we can pass in the value after the dimension:

int dimension = 4;
double value = 1.0;
Vector vector(dimension, value);

If we know the values of the vector beforehand, we can directly initialize a Vector with those values:

Vector vector({1.0, 7.0, 0.0, 2.0});

Indexing

To access an individual element of a Vector, we use the array index operator [].

For example, let vector \(x = \begin{bmatrix} 1 \\ 7 \\ 0 \\ 2 \end{bmatrix}\). To access the \(i\)th element of \(x\):

Vector vector({1.0, 7.0, 0.0, 2.0});
double x_i = vector[1];

It is important to note that this is 0-based indexing. That is, the first element is \(x_0\). In the above example, \(x_1\) will set \(x_i := 7.0\).

Scaling

To scale a given vector, we simply use the overloaded * operator:

Vector vector({1.0, 7.0, 0.0, 2.0});
Vector scaled_vector = 2.0 * vector;

We can also scale in place:

Vector vector({1.0, 7.0, 0.0, 2.0});
vector *= 2.0;

Division is also supported:

Vector vector({1.0, 7.0, 0.0, 2.0});
Vector scaled_vector = vector / 2.0;

And division in place:

Vector vector({1.0, 7.0, 0.0, 2.0});
vector /= 2.0;

Addition

To add two vectors, we use the overloaded + operator:

Vector x({1.0, 7.0, 0.0, 2.0});
Vector y({3.0, 4.0, 1.0, 8.0});

Vector z = x + y;

This can also be done in place:

Vector x({1.0, 7.0, 0.0, 2.0});
Vector y({3.0, 4.0, 1.0, 8.0});

x += y;

Subtraction works similarly:

Vector x({1.0, 7.0, 0.0, 2.0});
Vector y({3.0, 4.0, 1.0, 8.0});

Vector z = x - y;

This can also be done in place:

Vector x({1.0, 7.0, 0.0, 2.0});
Vector y({3.0, 4.0, 1.0, 8.0});

x -= y;

Inner Product

To compute the inner product of two vectors, we use the Mult function.

For example, let vector \(x = \begin{bmatrix} 1 \\ 7 \\ 0 \\ 2 \end{bmatrix}\) and let vector \(y = \begin{bmatrix} 3 \\ 4 \\ 1 \\ 8 \end{bmatrix}\).

To compute the inner product \(\alpha = y^Tx\):

Vector x({1.0, 7.0, 0.0, 2.0});
Vector y({3.0, 4.0, 1.0, 8.0});

double alpha = y.Mult(x);

\(L_2\) Norm

We can put some of these operations together to finally compute something useful.

For example, given a vector \(x\), we wish to compute

\[\left\Vert x \right\Vert_2 = \sqrt{\sum_{i=0}^{n-1} x_i^2} = \sqrt{x^Tx}\]

In code, this would be:

Vector x({1.0, 7.0, 0.0, 2.0});

double l2_norm = std::sqrt(x.Mult(x));

Finally, suppose we wish to normalize the vector \(x\) such that \(\left\Vert x \right\Vert_2 = 1.0\):

Vector x({1.0, 7.0, 0.0, 2.0});

x /= std::sqrt(x.Mult(x));