$include_dir="/home/hyper-archives/ublas/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [ublas] bindings for matrix_vector_range, matrix_vector_slice, bounded_matrix, bounded_vector
From: Markus Rickert (rickert_at_[hidden])
Date: 2008-10-22 18:29:24
Hi,
>> Thank you. I added it to the test. I also added 
>> [...]
>> at the top of the file. Is this OK?
this is fine, thanks. I've attached another patch that includes 
matrix_traits for std_vector.hpp, std_valarray.hpp and c_array.hpp. Or 
are these supposed to go into vector2.hpp? See also test.cpp for test code.
>> I added your patch, but commented out the stride1/stride2 functionality in ublas_vector2.hpp.
>> In case the stride1/stride2 functionality is important, free accessor functions dense_matrix_stride1 and dense_matrix_stride2 should be created instead, where matrix_traits<M>::leading_dimension(m) / 1 would be returned, dependent on matrix_traits<M>::ordering_type.
> stride1 and stride2 are indeed a ublas issue since they are not used in
> any bindings code (BLAS or LAPACK e.g.). That is the reason why we took
> it out of the description of the bindings.
I guess this would look something like the attached code in 
dense_traits.hpp/dense_ordering.hpp (with test2.cpp)?
However, I think it's not possible to support matrix_traits for 
vector_slice, matrix_vector_range, matrix_vector_slice, matrix_row, 
matrix_column this way (for bindings relying on leading_dimension).
Using stride1/stride2 it would be possible to allow at least IPP 
functions to handle these.
Markus
Index: traits/c_array.hpp
===================================================================
--- traits/c_array.hpp	(revision 49434)
+++ traits/c_array.hpp	(working copy)
@@ -19,6 +19,7 @@
 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS 
 
 #include <boost/numeric/bindings/traits/vector_traits.hpp>
+#include <boost/numeric/bindings/traits/matrix_traits.hpp>
 
 namespace boost { namespace numeric { namespace bindings { namespace traits {
 
@@ -41,7 +42,38 @@
     static int size (vector_type&) { return N; } 
     static int stride (vector_type&) { return 1; } 
   }; 
+  
+  // built-in array as matrix (nx1)
+  template <typename T, std::size_t N, typename V>
+  struct matrix_detail_traits<T[N], V> 
+  {
+#ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
+    BOOST_STATIC_ASSERT( 
+      (boost::is_same< 
+         T[N], 
+         typename boost::remove_const<V>::type 
+       >::value) );
+#endif
 
+    typedef T identifier_type [N];
+    typedef V matrix_type; 
+    typedef general_t matrix_structure; 
+    typedef column_major_t ordering_type; 
+
+    typedef T value_type; 
+    typedef typename default_vector_traits< V, T >::pointer pointer; 
+
+    static pointer storage (matrix_type& v) {
+      return vector_traits<matrix_type>::storage (v); 
+    }
+    static std::ptrdiff_t num_rows (matrix_type& v) { return N; } 
+    static std::ptrdiff_t num_columns (matrix_type&) { return 1; }
+    static std::ptrdiff_t storage_size (matrix_type& v) { return N; }
+//    static std::ptrdiff_t stride1 (matrix_type& v) { return vector_traits<V>::stride (v); } 
+//    static std::ptrdiff_t stride2 (matrix_type&) { return 1; }
+    static std::ptrdiff_t leading_dimension (matrix_type& v) { return N; }
+  }; 
+
 }}}}
 
 #else // BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS 
Index: traits/std_valarray.hpp
===================================================================
--- traits/std_valarray.hpp	(revision 49434)
+++ traits/std_valarray.hpp	(working copy)
@@ -22,6 +22,7 @@
 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS 
 
 #include <boost/numeric/bindings/traits/vector_traits.hpp>
+#include <boost/numeric/bindings/traits/matrix_traits.hpp>
 #include <valarray>
 
 
@@ -50,7 +51,38 @@
       return &ncva[0];
     }
   }; 
+  
+  // std::valarray<> treated as matrix (nx1)
+  template <typename T, typename V>
+  struct matrix_detail_traits<std::valarray<T>, V> 
+  {
+#ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
+    BOOST_STATIC_ASSERT( 
+      (boost::is_same< 
+         std::valarray<T>, 
+         typename boost::remove_const<V>::type 
+       >::value) );
+#endif
 
+    typedef std::valarray<T> identifier_type;
+    typedef V matrix_type; 
+    typedef general_t matrix_structure; 
+    typedef column_major_t ordering_type; 
+
+    typedef T value_type; 
+    typedef typename default_vector_traits< V, T >::pointer pointer; 
+
+    static pointer storage (matrix_type& v) {
+      return vector_traits<matrix_type>::storage (v); 
+    }
+    static std::ptrdiff_t num_rows (matrix_type& v) { return v.size(); } 
+    static std::ptrdiff_t num_columns (matrix_type&) { return 1; }
+    static std::ptrdiff_t storage_size (matrix_type& v) { return v.size(); }
+//    static std::ptrdiff_t stride1 (matrix_type& v) { return vector_traits<V>::stride (v); } 
+//    static std::ptrdiff_t stride2 (matrix_type&) { return 1; }
+    static std::ptrdiff_t leading_dimension (matrix_type& v) { return v.size(); }
+  }; 
+
 }}}}  
 
 #else // BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS 
Index: traits/std_vector.hpp
===================================================================
--- traits/std_vector.hpp	(revision 49434)
+++ traits/std_vector.hpp	(working copy)
@@ -15,6 +15,7 @@
 #define BOOST_NUMERIC_BINDINGS_TRAITS_STD_VECTOR_H
 
 #include <boost/numeric/bindings/traits/vector_traits.hpp>
+#include <boost/numeric/bindings/traits/matrix_traits.hpp>
 
 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS 
 
@@ -39,7 +40,38 @@
 
     static pointer storage (vector_type& v) { return &v.front(); }
   }; 
+  
+  // std::vector<> treated as matrix (nx1)
+  template <typename T, typename Alloc, typename V>
+  struct matrix_detail_traits<std::vector<T, Alloc>, V> 
+  {
+#ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
+    BOOST_STATIC_ASSERT( 
+      (boost::is_same< 
+         std::vector<T, Alloc>, 
+         typename boost::remove_const<V>::type 
+       >::value) );
+#endif
 
+    typedef std::vector<T, Alloc> identifier_type;
+    typedef V matrix_type; 
+    typedef general_t matrix_structure; 
+    typedef column_major_t ordering_type; 
+
+    typedef T value_type; 
+    typedef typename default_vector_traits< V, T >::pointer pointer; 
+
+    static pointer storage (matrix_type& v) {
+      return vector_traits<matrix_type>::storage (v); 
+    }
+    static std::ptrdiff_t num_rows (matrix_type& v) { return v.size(); } 
+    static std::ptrdiff_t num_columns (matrix_type&) { return 1; }
+    static std::ptrdiff_t storage_size (matrix_type& v) { return v.size(); }
+//    static std::ptrdiff_t stride1 (matrix_type& v) { return vector_traits<V>::stride (v); } 
+//    static std::ptrdiff_t stride2 (matrix_type&) { return 1; }
+    static std::ptrdiff_t leading_dimension (matrix_type& v) { return v.size(); }
+  }; 
+
 }}}}  
 
 #endif // BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS 
#ifndef BOOST_NUMERIC_BINDINGS_TRAITS_DENSE_TRAITS_H
#define BOOST_NUMERIC_BINDINGS_TRAITS_DENSE_TRAITS_H
#include <boost/numeric/bindings/traits/config.hpp> 
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS 
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/detail/dense_ordering.hpp>
namespace boost { namespace numeric { namespace bindings { namespace traits {
  template <typename M>
  inline
  std::ptrdiff_t 
  dense_matrix_stride1 (M& m) { 
    return detail::dense_ordering< typename matrix_traits<M>::ordering_type >::stride1 (m); 
  }
  template <typename M>
  inline
  std::ptrdiff_t 
  dense_matrix_stride2 (M& m) { 
    return detail::dense_ordering< typename matrix_traits<M>::ordering_type >::stride2 (m); 
  }
}}}}  
#else // BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS 
#error with your compiler dense matrices cannot be used in bindings
#endif // BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS 
#endif // BOOST_NUMERIC_BINDINGS_TRAITS_DENSE_TRAITS_H
#ifndef BOOST_NUMERIC_BINDINGS_TRAITS_DETAIL_DENSE_ORDERING_H
#define BOOST_NUMERIC_BINDINGS_TRAITS_DETAIL_DENSE_ORDERING_H
#include <boost/numeric/ublas/fwd.hpp> 
namespace boost { namespace numeric { namespace bindings { namespace traits {
  namespace detail {
    
    template <typename StOrdTag>
    struct dense_ordering {};
    
    template<> 
    struct dense_ordering<row_major_t> {
      typedef row_major_t type; 
      
      template <typename M>
      static std::ptrdiff_t stride1( M const& m ) {
        return leading_dimension (m) ;
      }
      
      template <typename M>
      static std::ptrdiff_t stride2( M const& m ) {
        return 1 ;
      }
    };
    
    template<> 
    struct dense_ordering<column_major_t> {
      typedef column_major_t type; 
      
      template <typename M>
      static std::ptrdiff_t stride1( M const& m ) {
        return 1 ;
      }
      
      template <typename M>
      static std::ptrdiff_t stride2( M const& m ) {
        return leading_dimension (m) ;
      }
    };
    
  }
}}}}
#endif // BOOST_NUMERIC_BINDINGS_TRAITS_DETAIL_DENSE_ORDERING_H