From 4e3b20267a08f38375e89d03877b8865a16fce0d Mon Sep 17 00:00:00 2001
From: Simon Praetorius <simon.praetorius@tu-dresden.de>
Date: Tue, 24 Mar 2015 22:08:33 +0000
Subject: [PATCH] small workaround for mtl dense_vector 'bug' when using const
 value_type

---
 AMDiS/src/MatrixVectorOperations.h | 28 ++++++++++++++--------------
 AMDiS/src/operations/norm.hpp      |  4 ++--
 AMDiS/src/operations/product.hpp   |  4 ++--
 AMDiS/src/traits/basic.hpp         |  9 +++++++++
 4 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/AMDiS/src/MatrixVectorOperations.h b/AMDiS/src/MatrixVectorOperations.h
index 6100b41c..f3bfb1d9 100644
--- a/AMDiS/src/MatrixVectorOperations.h
+++ b/AMDiS/src/MatrixVectorOperations.h
@@ -159,7 +159,8 @@ namespace AMDiS {
 
   /// vector *= scalar (elementwise)
   template <typename T, typename S>
-  Vector<T>& operator*=(Vector<T>& v, S scal)
+  typename enable_if< traits::is_multiplicable<S, T>, Vector<T> >::type &
+  operator*=(Vector<T>& v, S scal)
   {
     T *vIt;
     for (vIt = v.begin(); vIt != v.end(); ++vIt) 
@@ -169,17 +170,17 @@ namespace AMDiS {
 
   /// vector := vector * scalar (elementwise)
   template <typename T, typename S>
-  Vector<typename traits::mult_type<T, S>::type>
-  operator*(Vector<T> const& v, S scal) 
+  typename enable_if< traits::is_multiplicable<S, T>, Vector<T> >::type
+  operator*(Vector<T> result, S scal) 
   {
-    Vector<typename traits::mult_type<T, S>::type> result = v;
     result *= scal;
     return result;
   }
 
   /// vector /= scalar (elementwise)
   template <typename T, typename S>
-  Vector<T>& operator/=(Vector<T>& v, S scal)
+  typename enable_if< traits::is_multiplicable<S, T>, Vector<T> >::type &
+  operator/=(Vector<T>& v, S scal)
   {
     T *vIt;
     for (vIt = v.begin(); vIt != v.end(); ++vIt) 
@@ -189,10 +190,9 @@ namespace AMDiS {
 
   /// vector := vector / scalar (elementwise)
   template <typename T, typename S>
-  Vector<typename traits::mult_type<T, S>::type>
-  operator/(Vector<T> const& v, S scal) 
+  typename enable_if< traits::is_multiplicable<S, T>, Vector<T> >::type
+  operator/(Vector<T> result, S scal) 
   {
-    Vector<typename traits::mult_type<T, S>::type> result = v;
     result /= scal;
     return result;
   }
@@ -319,7 +319,7 @@ namespace AMDiS {
   
   /// vector := vector * scalar (elementwise)
   template<typename T, typename S>
-  WorldVector<T>
+  typename enable_if< traits::is_multiplicable<S, T>, WorldVector<T> >::type
   operator*(WorldVector<T> const& v, S scal)
   {
     WorldVector<T> result = v;
@@ -329,7 +329,7 @@ namespace AMDiS {
 
   /// vector := scalar * vector (elementwise)
   template<typename T, typename S>
-  WorldVector<T>
+  typename enable_if< traits::is_multiplicable<S, T>, WorldVector<T> >::type
   operator*(S scal, WorldVector<T> const& v)
   {
     WorldVector<T> result = v;
@@ -339,7 +339,7 @@ namespace AMDiS {
 
   /// vector := vector / scalar (elementwise)
   template<typename T, typename S>
-  WorldVector<T>
+  typename enable_if< traits::is_multiplicable<S, T>, WorldVector<T> >::type
   operator/(WorldVector<T> const& v, S scal)
   {
     WorldVector<T> result = v;
@@ -359,7 +359,7 @@ namespace AMDiS {
   
   /// matrix := matrix * scalar (elementwise)
   template <typename T, typename S>
-  WorldMatrix<T>
+  typename enable_if< traits::is_multiplicable<S, T>, WorldMatrix<T> >::type
   operator*(WorldMatrix<T> const& m, S scal)
   {
     WorldMatrix<T> result = m;
@@ -369,7 +369,7 @@ namespace AMDiS {
 
   /// matrix := scalar * matrix (elementwise)
   template <typename T, typename S>
-  WorldMatrix<T>
+  typename enable_if< traits::is_multiplicable<S, T>, WorldMatrix<T> >::type
   operator*(S scal, WorldMatrix<T> const& m)
   {
     WorldMatrix<T> result = m;
@@ -379,7 +379,7 @@ namespace AMDiS {
 
   /// matrix := matrix / scalar (elementwise)
   template <typename T, typename S>
-  WorldMatrix<T>
+  typename enable_if< traits::is_multiplicable<S, T>, WorldMatrix<T> >::type
   operator/(WorldMatrix<T> const& m, S scal)
   {
     WorldMatrix<T> result = m;
diff --git a/AMDiS/src/operations/norm.hpp b/AMDiS/src/operations/norm.hpp
index 251dcc85..1dbe744e 100644
--- a/AMDiS/src/operations/norm.hpp
+++ b/AMDiS/src/operations/norm.hpp
@@ -59,7 +59,7 @@ namespace AMDiS
     
     using namespace mtl::vector;
     typedef parameters<mtl::col_major, non_fixed::dimension, false, size_type> param;
-    mtl::dense_vector<const value_type, param> tmp(AMDiS::size(v), v.begin());
+    mtl::dense_vector<value_type, param> tmp(AMDiS::size(v), const_cast<value_type*>(v.begin()));
     return mtl::two_norm(tmp);
   }
   
@@ -110,7 +110,7 @@ namespace AMDiS
     
     using namespace mtl::vector;
     typedef parameters<mtl::col_major, non_fixed::dimension, false, size_type> param;
-    mtl::dense_vector<const value_type, param> tmp(AMDiS::size(v), v.begin());
+    mtl::dense_vector<value_type, param> tmp(AMDiS::size(v), const_cast<value_type*>(v.begin()));
     return mtl::vector::one_norm(tmp);
   }
   
diff --git a/AMDiS/src/operations/product.hpp b/AMDiS/src/operations/product.hpp
index 5aad9ac1..79fde642 100644
--- a/AMDiS/src/operations/product.hpp
+++ b/AMDiS/src/operations/product.hpp
@@ -64,8 +64,8 @@ namespace AMDiS
     using namespace mtl::vector;
     typedef parameters<mtl::col_major, non_fixed::dimension, false, size_type1> param1;
     typedef parameters<mtl::col_major, non_fixed::dimension, false, size_type2> param2;
-    mtl::dense_vector<const value_type1, param1> tmp1(AMDiS::size(v1), v1.begin());
-    mtl::dense_vector<const value_type2, param2> tmp2(AMDiS::size(v2), v2.begin());
+    mtl::dense_vector<value_type1, param1> tmp1(AMDiS::size(v1), const_cast<value_type1*>(v1.begin()));
+    mtl::dense_vector<value_type2, param2> tmp2(AMDiS::size(v2), const_cast<value_type2*>(v2.begin()));
     return mtl::dot(tmp1, tmp2);
   }
   
diff --git a/AMDiS/src/traits/basic.hpp b/AMDiS/src/traits/basic.hpp
index 3c6c2dec..5c95975c 100644
--- a/AMDiS/src/traits/basic.hpp
+++ b/AMDiS/src/traits/basic.hpp
@@ -61,6 +61,15 @@ namespace AMDiS
     // dummy type
     typedef boost::numeric::ublas::error_cant_deduce_type no_valid_type;
   
+    template <class A, class B>
+    struct is_multiplicable : boost::mpl::not_< 
+	boost::is_same< typename mtl::Multiplicable<A,B>::result_type, 
+		        no_valid_type > > {};
+  
+    template <class A, class B>
+    struct is_addable : boost::mpl::not_< 
+	boost::is_same< typename mtl::Addable<A,B>::result_type, 
+			no_valid_type > > {};
       
 #ifdef HAS_CPP11
     template <typename T>
-- 
GitLab