Boost logo

Ublas :

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