apply std::pow to vector or matrix

I followed the UBLAS extensions here: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Examples_-_Ho... and I figured out how to extend functions like "exp" and "log" to act on a vector. But, those are functions of one argument. What I want is to be able to apply a function with one fixed argument, like std::pow, to a vector for some exponent exp, so I would like the code to look like: vector<double> v( 100 ); double exponent = 2.1; // some exponent value // ... fill v ... std::cout << apply_to_all( v, functor::my_pow<double>(exponent) ) << std::endl; std::cout << apply_to_all<functor::my_pow<double>(exponent) >( v ) << std::endl; OR std::cout << apply_to_all( v, functor::my_pow<double>() , exponent) << std::endl; How can I do this? I tried overloading apply_to_all and writing constructor code, but it didn't work because the return type of the apply function is static. P.S. I tried posting this to ublas lists, but got a message saying that my e-mail address is not registered. I guess that list is only for developers. Thanks, Max

On Mon, Jul 5, 2010 at 9:18 PM, Max S. Kaznady <max.kaznady@gmail.com>wrote:
I followed the UBLAS extensions here:
http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Examples_-_Ho... and I figured out how to extend functions like "exp" and "log" to act on a vector.
But, those are functions of one argument. What I want is to be able to apply a function with one fixed argument, like std::pow, to a vector for some exponent exp, so I would like the code to look like: vector<double> v( 100 ); double exponent = 2.1; // some exponent value // ... fill v ... std::cout << apply_to_all( v, functor::my_pow<double>(exponent) ) << std::endl; std::cout << apply_to_all<functor::my_pow<double>(exponent) >( v ) << std::endl; OR std::cout << apply_to_all( v, functor::my_pow<double>() , exponent) << std::endl;
How can I do this? I tried overloading apply_to_all and writing constructor code, but it didn't work because the return type of the apply function is static.
P.S. I tried posting this to ublas lists, but got a message saying that my e-mail address is not registered. I guess that list is only for developers.
Hi Max I'm not familiar with Ublas, but does this achieve the effect you're after #include <vector> #include <algorithm> #include <math.h> #include "boost/bind.hpp" int main( ) { std::vector<double> v; double exponent = 2.1; std::transform( v.begin(), v.end(), v.begin(), boost::bind( pow, _1, exponent ) ); } Regards, - Rob.

Hi Robert, Yep, the following works great. Not sure why the same code doesn't work when I have it in my larger project, but I guess that's for me to figure out. There is still the problem with the std::for_each, see below: #include <iostream> #include <vector> #include <algorithm> #include <math.h> #include "boost/bind.hpp" #include <boost/numeric/ublas/vector.hpp> #include <boost/numeric/ublas/io.hpp> int main( ) { boost::numeric::ublas::vector<double> v(10); double exponent = 2.1; std::fill(v.begin(), v.end(), 8.0); // The following works just fine: std::transform( v.begin(), v.end(), v.begin(), boost::bind( pow, _1, exponent ) ); // But the for_each doesn't apply the power function, just leaves the vector unaltered std::for_each( v.begin(), v.end(), boost::bind( pow, _1, exponent ) ); // Print the result std::cout<< v << std::endl; return 0; } Compiled with: g++ -O2 -Wfatal-errors -Wall -g -ansi -I/usr/local/boost/include -o main main.cpp Cheers, Max On Tue, Jul 6, 2010 at 3:56 AM, Robert Jones <robertgbjones@gmail.com> wrote:
On Mon, Jul 5, 2010 at 9:18 PM, Max S. Kaznady <max.kaznady@gmail.com> wrote:
I followed the UBLAS extensions here:
http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Examples_-_Ho... and I figured out how to extend functions like "exp" and "log" to act on a vector.
But, those are functions of one argument. What I want is to be able to apply a function with one fixed argument, like std::pow, to a vector for some exponent exp, so I would like the code to look like: vector<double> v( 100 ); double exponent = 2.1; // some exponent value // ... fill v ... std::cout << apply_to_all( v, functor::my_pow<double>(exponent) ) << std::endl; std::cout << apply_to_all<functor::my_pow<double>(exponent) >( v ) << std::endl; OR std::cout << apply_to_all( v, functor::my_pow<double>() , exponent) << std::endl;
How can I do this? I tried overloading apply_to_all and writing constructor code, but it didn't work because the return type of the apply function is static.
P.S. I tried posting this to ublas lists, but got a message saying that my e-mail address is not registered. I guess that list is only for developers.
Hi Max
I'm not familiar with Ublas, but does this achieve the effect you're after
#include <vector> #include <algorithm> #include <math.h> #include "boost/bind.hpp"
int main( ) { std::vector<double> v; double exponent = 2.1; std::transform( v.begin(), v.end(), v.begin(), boost::bind( pow, _1, exponent ) ); }
Regards,
- Rob.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On Wed, Jul 7, 2010 at 3:30 AM, Max S. Kaznady <max.kaznady@gmail.com>wrote:
Hi Robert,
Yep, the following works great. Not sure why the same code doesn't work when I have it in my larger project, but I guess that's for me to figure out.
There is still the problem with the std::for_each, see below:
#include <iostream> #include <vector> #include <algorithm> #include <math.h> #include "boost/bind.hpp" #include <boost/numeric/ublas/vector.hpp> #include <boost/numeric/ublas/io.hpp>
int main( ) { boost::numeric::ublas::vector<double> v(10); double exponent = 2.1; std::fill(v.begin(), v.end(), 8.0); // The following works just fine: std::transform( v.begin(), v.end(), v.begin(), boost::bind( pow, _1, exponent ) ); // But the for_each doesn't apply the power function, just leaves the vector unaltered std::for_each( v.begin(), v.end(), boost::bind( pow, _1, exponent ) ); // Print the result std::cout<< v << std::endl;
return 0; }
Compiled with: g++ -O2 -Wfatal-errors -Wall -g -ansi -I/usr/local/boost/include -o main main.cpp
Hi Max I haven't taken the time to try this, but does this do the trick? std::for_each(v.begin(), v.end(), boost::bind(pow, boost::ref(_1), exponent)); Cheers - Rob.

On Wed, Jul 7, 2010 at 8:06 AM, Robert Jones <robertgbjones@gmail.com>wrote:
On Wed, Jul 7, 2010 at 3:30 AM, Max S. Kaznady <max.kaznady@gmail.com>wrote:
Hi Robert,
Yep, the following works great. Not sure why the same code doesn't work when I have it in my larger project, but I guess that's for me to figure out.
There is still the problem with the std::for_each, see below:
#include <iostream> #include <vector> #include <algorithm> #include <math.h> #include "boost/bind.hpp" #include <boost/numeric/ublas/vector.hpp> #include <boost/numeric/ublas/io.hpp>
int main( ) { boost::numeric::ublas::vector<double> v(10); double exponent = 2.1; std::fill(v.begin(), v.end(), 8.0); // The following works just fine: std::transform( v.begin(), v.end(), v.begin(), boost::bind( pow, _1, exponent ) ); // But the for_each doesn't apply the power function, just leaves the vector unaltered std::for_each( v.begin(), v.end(), boost::bind( pow, _1, exponent ) ); // Print the result std::cout<< v << std::endl;
return 0; }
Compiled with: g++ -O2 -Wfatal-errors -Wall -g -ansi -I/usr/local/boost/include -o main main.cpp
Hi Max
I haven't taken the time to try this, but does this do the trick?
std::for_each(v.begin(), v.end(), boost::bind(pow, boost::ref(_1), exponent));
Cheers
- Rob.
Forget that, it was complete gibberish. Your example doesn't do as you expect because std::pow does not alter its argument, but rather returns a result. You have to do something with the result of std::pow, hence my original use of transform. To understand this look at this example. #include <vector> #include <algorithm> #include <math.h> #include "boost/bind.hpp" void my_pow( double & val, double exponent ) { val = pow( val, exponent ); } int main( ) { std::vector<double> v; double exponent = 2.1; std::for_each( v.begin(), v.end(), boost::bind( my_pow, _1, exponent ) ); } HTH - Rob.

Great example, thanks! Before your post, I wrote something like: namespace my { void my_vec_pow(boost::numeric::ublas::vector<double> &vec, double expon) { boost::numeric::ublas::vector<double>::iterator it; for (it = vec.begin(); it != vec.end(); ++it) *it = std::pow(*it, expon); } } I'm just curious, but from performance perspective, how much more efficient is it to use iterators and functors? I would assume that most compilers can exploit this to improve memory management and speed up the computation... I'll write some benchmarks later on this week, efficiency is crucial for what I'm doing. Max On Wed, Jul 7, 2010 at 3:49 AM, Robert Jones <robertgbjones@gmail.com> wrote:
On Wed, Jul 7, 2010 at 8:06 AM, Robert Jones <robertgbjones@gmail.com> wrote:
On Wed, Jul 7, 2010 at 3:30 AM, Max S. Kaznady <max.kaznady@gmail.com> wrote:
Hi Robert,
Yep, the following works great. Not sure why the same code doesn't work when I have it in my larger project, but I guess that's for me to figure out.
There is still the problem with the std::for_each, see below:
#include <iostream> #include <vector> #include <algorithm> #include <math.h> #include "boost/bind.hpp" #include <boost/numeric/ublas/vector.hpp> #include <boost/numeric/ublas/io.hpp>
int main( ) { boost::numeric::ublas::vector<double> v(10); double exponent = 2.1; std::fill(v.begin(), v.end(), 8.0); // The following works just fine: std::transform( v.begin(), v.end(), v.begin(), boost::bind( pow, _1, exponent ) ); // But the for_each doesn't apply the power function, just leaves the vector unaltered std::for_each( v.begin(), v.end(), boost::bind( pow, _1, exponent ) ); // Print the result std::cout<< v << std::endl;
return 0; }
Compiled with: g++ -O2 -Wfatal-errors -Wall -g -ansi -I/usr/local/boost/include -o main main.cpp
Hi Max
I haven't taken the time to try this, but does this do the trick?
std::for_each(v.begin(), v.end(), boost::bind(pow, boost::ref(_1), exponent));
Cheers
- Rob.
Forget that, it was complete gibberish. Your example doesn't do as you expect because std::pow does not alter its argument, but rather returns a result. You have to do something with the result of std::pow, hence my original use of transform.
To understand this look at this example.
#include <vector> #include <algorithm> #include <math.h> #include "boost/bind.hpp"
void my_pow( double & val, double exponent ) { val = pow( val, exponent ); }
int main( ) { std::vector<double> v; double exponent = 2.1;
std::for_each( v.begin(), v.end(), boost::bind( my_pow, _1, exponent ) ); }
HTH
- Rob.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On Wed, Jul 7, 2010 at 4:45 PM, Max S. Kaznady <max.kaznady@gmail.com>wrote:
Great example, thanks! Before your post, I wrote something like:
namespace my { void my_vec_pow(boost::numeric::ublas::vector<double> &vec, double expon) { boost::numeric::ublas::vector<double>::iterator it; for (it = vec.begin(); it != vec.end(); ++it) *it = std::pow(*it, expon); } }
I'm just curious, but from performance perspective, how much more efficient is it to use iterators and functors? I would assume that most compilers can exploit this to improve memory management and speed up the computation... I'll write some benchmarks later on this week, efficiency is crucial for what I'm doing.
By and large, in my experience, it's barely measurable, at least for simple cases. When you write for(i=v.begin(); i!=v.end();....) v.end() is evaluated on each iteration, which may have some effect, depending on type of v, but for simple vectors it's probably inlined anyway. (there's folks on here that know much more about it than I do). With the new Boost.Range algorithms there's also some syntactic simplification as you can write for(v,fn); which is a real plus if v is complicated expression, since you don't have to evaluate it twice or even put it in an explicit variable. Cheers - Rob.

I wrote some benchmarks for Boost and GSL where I initialize a vector of random numbers and then raise it to some random exponent, and I redo the operations a certain number of times and report the average time. std::transform and std::for_each take the same time, GSL's filling in manually and Boosts's filling in manually also take the same time BUT, manual fil is a bit faster than using std::transform and std::for_each. Any ideas why? Runtimes: Boost vector initialization: 0.000000000000000 GSL vector initialization: 0.000000000000000 Boost transform avg time: 0.002141000000000 Boost for_each avg time: 0.002094000000000 Boost manual fill avg time: 0.001811000000000 GSL avg time: 0.001820000000000 The code is below: /* * main.cpp * * Created on: 2010-07-08 * Author: max */ #include <iostream> #include <vector> #include <algorithm> #include <math.h> #include <fstream> #include <ctime> // std::time #include <boost/bind.hpp> #include <boost/numeric/ublas/vector.hpp> #include <boost/numeric/ublas/io.hpp> #include <boost/timer.hpp> // time the runs // For random number generation #include <boost/random/linear_congruential.hpp> #include <boost/random/uniform_int.hpp> #include <boost/random/uniform_real.hpp> #include <boost/random/variate_generator.hpp> // Sun CC doesn't handle boost::iterator_adaptor yet #if !defined(__SUNPRO_CC) || (__SUNPRO_CC > 0x530) #include <boost/generator_iterator.hpp> #endif #ifdef BOOST_NO_STDC_NAMESPACE namespace std { using ::time; } #endif // This is a typedef for a random number generator. // Try boost::mt19937 or boost::ecuyer1988 instead of boost::minstd_rand typedef boost::minstd_rand base_generator_type; // GSL includes #include <stdio.h> #include <gsl/gsl_vector.h> void my_pow(double & val, double exponent) { val = std::pow(val, exponent); } int main() { // Size of assigned vector unsigned N = 10000; // number of times to repeat the simulation // unsigned numrepeat = 10000; // exponent to use double exponent; // = 12.12345678901234; // value to exponentiate double fill_val; // = 1.12345678901234; // Define a random number generator and initialize it with a reproducible // seed. // (The seed is unsigned, otherwise the wrong overload may be selected // when using mt19937 as the base_generator_type.) base_generator_type generator(42u); // Define a uniform random number distribution which produces "double" // values between 0 and 1 (0 inclusive, 1 exclusive). boost::uniform_real<> uni_dist(0, 1); boost::variate_generator<base_generator_type&, boost::uniform_real<> > uni( generator, uni_dist); /* * Change seed to something else. * * Caveat: std::time(0) is not a very good truly-random seed. When * called in rapid succession, it could return the same values, and * thus the same random number sequences could ensue. If not the same * values are returned, the values differ only slightly in the * lowest bits. A linear congruential generator with a small factor * wrapped in a uniform_smallint (see experiment) will produce the same * values for the first few iterations. This is because uniform_smallint * takes only the highest bits of the generator, and the generator itself * needs a few iterations to spread the initial entropy from the lowest bits * to the whole state. */ // Set the generator later for each piece of code //generator.seed(static_cast<unsigned int> (std::time(0))); // Vector of times boost::numeric::ublas::vector<double> times(N); // Boost timer boost::timer t; std::cout.precision(15); t.restart(); boost::numeric::ublas::vector<double> boost_v(N); std::cout << "Boost vector initialization: " << std::endl; std::cout << std::fixed << t.elapsed() << std::endl; t.restart(); gsl_vector * gsl_v = gsl_vector_alloc(N); std::cout << "GSL vector initialization: " << std::endl; std::cout << std::fixed << t.elapsed() << std::endl; // Filling Boost using std::transform generator.seed(static_cast<unsigned int> (std::time(0))); for (unsigned i = 0; i < N; ++i) { fill_val = uni(); exponent = 2.0 + uni(); t.restart(); std::fill(boost_v.begin(), boost_v.end(), fill_val); std::transform(boost_v.begin(), boost_v.end(), boost_v.begin(), boost::bind(pow, _1, exponent)); times(i) = t.elapsed(); } std::cout << "Boost transform avg time: " << std::endl; std::cout << std::fixed << boost::numeric::ublas::sum(times) / (double) N << std::endl; // Filling Boost using std::for_each generator.seed(static_cast<unsigned int> (std::time(0))); for (unsigned i = 0; i < N; ++i) { fill_val = uni(); exponent = 2.0 + uni(); t.restart(); std::fill(boost_v.begin(), boost_v.end(), fill_val); std::for_each(boost_v.begin(), boost_v.end(), boost::bind(my_pow, _1, exponent)); times(i) = t.elapsed(); } std::cout << "Boost for_each avg time: " << std::endl; std::cout << std::fixed << boost::numeric::ublas::sum(times) / (double) N << std::endl; // Filling Boost manually generator.seed(static_cast<unsigned int> (std::time(0))); for (unsigned i = 0; i < N; ++i) { fill_val = uni(); exponent = 2.0 + uni(); t.restart(); for (unsigned j = 0; j<N; ++j) { boost_v(j) = std::pow(fill_val, exponent); } times(i) = t.elapsed(); } std::cout << "Boost manual fill avg time: " << std::endl; std::cout << std::fixed << boost::numeric::ublas::sum(times) / (double) N << std::endl; // Filling GSL by hand generator.seed(static_cast<unsigned int> (std::time(0))); for (unsigned i = 0; i < N; ++i) { fill_val = uni(); exponent = 2.0 + uni(); t.restart(); for (unsigned j = 0; j<N; ++j) { gsl_vector_set(gsl_v, j, std::pow(fill_val, exponent)); } times(i) = t.elapsed(); } std::cout << "GSL avg time: " << std::endl; std::cout << std::fixed << boost::numeric::ublas::sum(times) / (double) N << std::endl; //de-allocate GSL gsl_vector_free(gsl_v); return 0; } Cheers, Max On Wed, Jul 7, 2010 at 12:13 PM, Robert Jones <robertgbjones@gmail.com> wrote:
On Wed, Jul 7, 2010 at 4:45 PM, Max S. Kaznady <max.kaznady@gmail.com> wrote:
Great example, thanks! Before your post, I wrote something like:
namespace my { void my_vec_pow(boost::numeric::ublas::vector<double> &vec, double expon) { boost::numeric::ublas::vector<double>::iterator it; for (it = vec.begin(); it != vec.end(); ++it) *it = std::pow(*it, expon); } }
I'm just curious, but from performance perspective, how much more efficient is it to use iterators and functors? I would assume that most compilers can exploit this to improve memory management and speed up the computation... I'll write some benchmarks later on this week, efficiency is crucial for what I'm doing.
By and large, in my experience, it's barely measurable, at least for simple cases. When you write
for(i=v.begin(); i!=v.end();....)
v.end() is evaluated on each iteration, which may have some effect, depending on type of v, but for simple vectors it's probably inlined anyway. (there's folks on here that know much more about it than I do).
With the new Boost.Range algorithms there's also some syntactic simplification as you can write
for(v,fn);
which is a real plus if v is complicated expression, since you don't have to evaluate it twice or even put it in an explicit variable.
Cheers
- Rob.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On Sun, Jul 11, 2010 at 10:35 PM, Max S. Kaznady <max.kaznady@gmail.com>wrote:
I wrote some benchmarks for Boost and GSL where I initialize a vector of random numbers and then raise it to some random exponent, and I redo the operations a certain number of times and report the average time.
std::transform and std::for_each take the same time, GSL's filling in manually and Boosts's filling in manually also take the same time BUT, manual fil is a bit faster than using std::transform and std::for_each. Any ideas why?
Runtimes: Boost vector initialization: 0.000000000000000 GSL vector initialization: 0.000000000000000 Boost transform avg time: 0.002141000000000 Boost for_each avg time: 0.002094000000000 Boost manual fill avg time: 0.001811000000000 GSL avg time: 0.001820000000000
Hi Max First thing I should say is that I am NOT in any sense an expert on the finer aspects of performance, so you may want to take anything I say with a large dose of salt! Second, I am reminded of the much quoted rules of optimization * Don't * Don't yet (for experts) * If you must, profile first Obviously you are profiling, but is it conclusive? What is the statistical uncertainty in your results, especially compared to the observed differences? All that said, I am unsurprised that hand rolled loops are a little faster. Using algorithms also uses a Boost.Bind invocation on each iteration, with all the overhead and lack of localisation that implies. You might want to try custom functors (inlined), to see how the performance numbers compare. However, stepping back, does your application really require the last word in performance? In most of your code, would clarity and expressiveness be more valuable that a small performance boost? Would your numbers be repeated in a more realistic application, and would these performance differences be significant against a broader background? Regards - Rob.

Actually, in the code I have to first fill a vector and then apply an operation, so if I'm just applying the operation then Boost is faster with iterators (manually, I can fill and apply the operation in one line of code; for iterators it's 2 lines). There is also quite a lot of uncertainty (I included unbiased std dev estimates): Boost transform avg time: 0.001945000000000 +/- 0.003958350900841 Boost for_each avg time: 0.001751000000000 +/- 0.003800716188346 Boost manual fill avg time: 0.001591000000000 +/- 0.003657876023829 GSL avg time: 0.001625000000000 +/- 0.003689273109110 I agree - using iterators it the way to go. The code is more readable, and you do actually get a performance boost, since most of the time you're not filling the vector and applying an operation - you are just applying an operation to a vector which has already been filled. Cheers, Max On Mon, Jul 12, 2010 at 4:02 AM, Robert Jones <robertgbjones@gmail.com> wrote:
On Sun, Jul 11, 2010 at 10:35 PM, Max S. Kaznady <max.kaznady@gmail.com> wrote:
I wrote some benchmarks for Boost and GSL where I initialize a vector of random numbers and then raise it to some random exponent, and I redo the operations a certain number of times and report the average time.
std::transform and std::for_each take the same time, GSL's filling in manually and Boosts's filling in manually also take the same time BUT, manual fil is a bit faster than using std::transform and std::for_each. Any ideas why?
Runtimes: Boost vector initialization: 0.000000000000000 GSL vector initialization: 0.000000000000000 Boost transform avg time: 0.002141000000000 Boost for_each avg time: 0.002094000000000 Boost manual fill avg time: 0.001811000000000 GSL avg time: 0.001820000000000
Hi Max
First thing I should say is that I am NOT in any sense an expert on the finer aspects of performance, so you may want to take anything I say with a large dose of salt!
Second, I am reminded of the much quoted rules of optimization
* Don't * Don't yet (for experts) * If you must, profile first
Obviously you are profiling, but is it conclusive? What is the statistical uncertainty in your results, especially compared to the observed differences?
All that said, I am unsurprised that hand rolled loops are a little faster. Using algorithms also uses a Boost.Bind invocation on each iteration, with all the overhead and lack of localisation that implies. You might want to try custom functors (inlined), to see how the performance numbers compare.
However, stepping back, does your application really require the last word in performance? In most of your code, would clarity and expressiveness be more valuable that a small performance boost? Would your numbers be repeated in a more realistic application, and would these performance differences be significant against a broader background?
Regards
- Rob.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Max S. Kaznady
-
Robert Jones