I'm not particularly familiar with the boost libraries, so there may be a more standard way to do this, but I think you can do what you want with iterators and the STL transform function template. The introduction to the uBLAS library documentation says its classes are designed to be compatible with the same iterator behavior that is used in the STL. The boost matrix and vector templates all have iterators which can be used to access the individual elements. The vector has begin()
and end()
, and the matrix has begin1()
, end1()
, begin2()
, and end2()
. The 1
varieties are column-wise iterators and the 2
varieties are row-wise iterators. See the boost documentation on VectorExpression and MatrixExpression for a little more info.
Using the STL transform
algorithm, you can apply a function to each element of an iterable sequence and assign the result to a different iterable sequence of the same length, or the same sequence. So to use this on a boost uBLAS vector you could do this:
using namespace boost::numeric::ublas;
// Create a 30 element vector of doubles
vector<double> vec(30);
// Assign 8.0 to each element.
std::fill(vec.begin(), vec.end(), 8.0);
// Perform the "Gamma" function on each element and assign the result back
// to the original element in the vector.
std::transform(vec.begin(), vec.end(), vec.begin(), boost::math::tgamma);
For a matrix it would be basically the same thing, you would use either the 1
or 2
family of iterators. Which one you choose to use depends on whether the memory layout of your matrix is row major or column major. A cursory scan of the uBLAS documentation leads me to believe that it could be either one, so you will need to examine the code and determine which one is being used so you choose the most efficient iteration order.
matrix<double> mat(30, 30);
.
.
.
std::transform(mat.begin1(), mat.end1(), mat.begin1(), boost::math::tgamma);
The function you pass as the last argument can be a function taking a single double argument and returning a double value. It can also be a functor.
This is not exactly the same as the vectorization example you cited, but it seems like it should be pretty close to what you want.