The primary purpose of this software is to maximize both performance and flexibility. That said, there are many things that can be done to make optimal use of this software.
Creating a new view of data is not only more memory efficient than copying the data into a new object, it is also much faster. One place where this can make a big difference is when you are accepting the result of a function that returns a vector or a matrix. Consider the following example:
Vec_DP x(10), y(10);
UniformGen gen(0);
x.fill(gen);
y = sqrt(x);
The sqrt() function creates a temporary vector, whose contents
are then copied into y. Now consider this alternative:
Vec_DP(10), y;
Uniformgen gen(0);
x.fill(gen);
y.reference(sqrt(x));
In this case, y simply takes over the data of the returned
vector. Not only does this eliminate the unnecessary copy operation, but it
also means that we do not have to allocate any memory to y
initially. Whenever possible, the VecMat routines return views of
already existing data, rather than new data. For example:
Vec_INT x(0, 10, 1), y(10);
y = x.slice(9, 10, -1);
This code generates a vector of integers starting with zero, and
incrementing by one up to 9. This vector is then copied into y in
reverse order. The slice() function returns a view, though, not a
unique object. This means that if x and y do not
explicitly need to each have their own data; we can improve performance with
the following code:
Vec_INT x(0, 10, 1), y;
y.reference(x.slice(9, 10, -1));
Here the variable y just takes over the view returned by the
slice. No extra memory is needed, and no copying is done.
Whenever possible, use the arithmetic assignment operators instead of the
binary arithmetic operators. Once again, this cuts down on the creation of
temporaries, and eliminates unnecessary copying. Similarly, it may be more
efficient to use the apply() function than to use the overloaded
math functions, because the overloaded math functions produce temporaries, and
then store the results of the function in them, whereas the
apply() function applies the function directly to the vector or
matrix. If you no longer need the original contents of the vector or matrix,
this is definitely the way to go.
() for Indexing
Matrices.It is much more efficient to index a matrix with the function call operator,
ie x(i, j), than with the C-style bracket notation, ie
x[I][j]. This is because the function call operator returns a
reference to the appropriate element, whereas the bracket operator returns an
iterator to the ith row, exactly like the rbegin()
member function. The C-style indexing is included only to provide compatibility
with other software, like Numerical Recipes in C++, which use this
notation for indexing matrices.