
Re the use of * operator I believe that * should be used for real true matrix multiplication not prod(a,b) or mult(a,b) It makes formulas easier to understand. For element by element multiplication I use & or &= The logical "and" isn't very useful for real numbers anyway. Regards Bill Shortall --- Kresimir Fresl <fresl@grad.hr> wrote:
(I added `Cc: ublas-dev' because I think that this can be interesting there, too.)
Toon Knapen wrote:
On Wednesday 06 November 2002 16:41, Hickman, Greg wrote:
Why isn't there an overloaded
matrix_expression operator* (const matrix_expression&, const matrix_expression&);
for peforming matrix multiplication?
This issue has been discussed before and the trouble IIRC is that operator* could also mean element-wise matrix multiplication. IMHO the optimal solution would be to take over all conventions from Matlab, a convention most are familiar with, but the element-wise multiplication operator '.*' can't be used in C++ ;( Another suggestion was to defined the element-wise and the normal multiplication in a different namespace (I still like this idea very much)
Let's try:
======================================================
#include <iostream> #include <boost/numeric/ublas/matrix.hpp> #include <boost/numeric/ublas/io.hpp>
namespace boost { namespace numeric { namespace ublas {
namespace normal { template<class E1, class E2> BOOST_UBLAS_INLINE typename matrix_matrix_binary_traits< typename E1::value_type, E1, typename E2::value_type, E2 >::result_type operator * (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) { return prod (e1, e2); } } }}}
int main() { boost::numeric::ublas::matrix<double> m1 (2, 2), m2 (2, 2); // init m1 & m2 using namespace boost::numeric::ublas::normal; std::cout << m1 * m2 << std::endl; }
======================================================
g++ 3.2 complains (`slightly' edited ;o) :
======================================================
ambiguous overload for `matrix<double>& * matrix<double>&' operator
candidates are:
(defined here): matrix_matrix_binary_traits<>::result_type operator*(const matrix_expression<E>&, const matrix_expression<E2>&) [with E1 = matrix<double>, E2 = matrix<double>]
(defined in `matrix_expression.hpp'): matrix_binary_scalar2_traits<>::result_type operator*(const matrix_expression<E>&, const T2&) [with E1 = matrix<double>, T2 = matrix<double>]
(defined in `matrix_expression.hpp'): matrix_binary_scalar1_traits<>::result_type operator*(const T1&, matrix_expression<E2>&) [with T1 = matrix<double>, E2 = matrix<double>]
======================================================
Comeau's compiler 4.3.0.1 gives similar diagnostics.
In `operator*(matrix_expression, T)' and `operator*(T, matrix_expression)' T is meant to be scalar, but compilers do not know this.
Let's try to tell them (probably can be simplified): ==================================================== template<class E2> BOOST_UBLAS_INLINE typename matrix_binary_scalar1_traits< typename E2::value_type, E2, scalar_multiplies<typename E2::value_type, typename E2::value_type>
::result_type operator * (const typename E2::value_type &e1, const matrix_expression<E2> &e2) { // etc. ====================================================
It works; not only `m1 * m2', but also `m1 * trans (m2)', `m1 * (m1 + m2)' etc.
Interesting thing is that if first parameter is declared as `const typename matrix_expression<E2>::value_type &e1' neither como nor g++ can find appropriate operator* for e.g. `2. * m1'.
So, header `operator_mult.hpp' can be: ================================================= #include <boost/numeric/ublas/vector.hpp> #include <boost/numeric/ublas/matrix.hpp> namespace boost { namespace numeric { namespace ublas {
namespace elemwise { // there are no elementwise multiplications in ublas, // at least not yet }
namespace normal {
template<class E1, class E2> BOOST_UBLAS_INLINE typename vector_scalar_binary_traits< E1, E2, vector_inner_prod< typename E1::value_type, typename E2::value_type, typename promote_traits< typename E1::value_type, typename E2::value_type >::promote_type > >::result_type operator * (const vector_expression<E1> &e1, const vector_expression<E2> &e2) { return inner_prod (e1, e2); }
template<class E1, class E2> BOOST_UBLAS_INLINE typename matrix_vector_binary1_traits< typename E1::value_type, E1, typename E2::value_type, E2 >::result_type operator * (const matrix_expression<E1> &e1, const vector_expression<E2> &e2) { return prod (e1, e2); }
template<class E1, class E2> BOOST_UBLAS_INLINE typename matrix_vector_binary2_traits< typename E1::value_type, E1, typename E2::value_type, E2 >::result_type operator * (const vector_expression<E1> &e1, const matrix_expression<E2> &e2) { return prod (e1, e2); }
template<class E1, class E2> BOOST_UBLAS_INLINE typename matrix_matrix_binary_traits< typename E1::value_type, E1, typename E2::value_type, E2 >::result_type operator * (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) { return prod (e1, e2);
=== message truncated === __________________________________________________ Do you Yahoo!? U2 on LAUNCH - Exclusive greatest hits videos http://launch.yahoo.com/u2