I'm trying to perform a matrix exponentiation, but I don't want to copy/paste my exponentiation function, and would rather use class templates. The problem is that for boost matrices, to multiply matrices, you use the prod
function (instead of operator*
).
It seems that g++ isn't able to figure out the template I want to use. The error I'm getting with the below code is
41:37: error: no matching function for call to 'my_pow(boost::numeric::ublas::matrix<int>&, int, <unresolved overloaded function type>)'
here's the code:
#include <iostream>
using namespace std;
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
typedef long long int64;
template <class T, class M> T my_pow(T b, int64 e, M mult)
{
if (e == 1) return b;
if (e % 2 == 1) return mult(b, my_pow(b, e - 1, mult));
T tmp = my_pow(b, e / 2, mult);
return mult(tmp, tmp);
}
template <class T> T my_pow(T b, int64 e) { return my_pow(b, e, multiplies<T>()); }
int main()
{
using namespace boost::numeric::ublas;
matrix<int> m(3, 3);
for (unsigned i = 0; i < m.size1(); ++i)
for (unsigned j = 0; j < m.size2(); ++j)
m(i, j) = 3 * i + j;
std::cout << m << std::endl;
std::cout << my_pow(m, 2, prod) << std::endl;
}
Is there any way to pass prod() to my_pow so the template resolves? Thanks.
It case it's not clear: b is the base, e is the exponent, and my_pow is to compute b^e
The reason why you are getting the compiler error is that there are many overloads of the
prod
function and at the call tomy_pow
the compiler needs to know which one to provide. The compiler cannot deduce that you will be applying the pow function to the first argument of your function, so it is at a loss here.One solution would be to explicitly cast the function pointer to the right type, but for the uBlas
prod
overloads determining the right type to cast to can be quite complex.Another solution is to create a polymorphic function object that delegates to the appropriate pow function. Note that the implementation below makes the huge assumption that
prod( m, m)
returns a value of the same type as m (or something convertible to it), but then again, this is the same assumption that yourmy_pow
makes and the temporaries that this creates are hard to avoid if the powere
can only be determined at run-time.An example of a polymorphic function class that would do the trick:
Now, if you change your call to
my_pow
into this:It should work (it does for me).