ublas_matrix.hpp

Go to the documentation of this file.
00001 /*
00002  * 
00003  * Copyright (c) 2002, 2003 Kresimir Fresl, Toon Knapen and Karl Meerbergen
00004  *
00005  * Distributed under the Boost Software License, Version 1.0.
00006  * (See accompanying file LICENSE_1_0.txt or copy at
00007  * http://www.boost.org/LICENSE_1_0.txt)
00008  *
00009  * KF acknowledges the support of the Faculty of Civil Engineering, 
00010  * University of Zagreb, Croatia.
00011  *
00012  */
00013 
00014 #ifndef BOOST_NUMERIC_BINDINGS_TRAITS_UBLAS_MATRIX_H
00015 #define BOOST_NUMERIC_BINDINGS_TRAITS_UBLAS_MATRIX_H
00016 
00017 #include <boost/numeric/bindings/traits/traits.hpp>
00018 
00019 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS 
00020 
00021 #ifndef BOOST_UBLAS_HAVE_BINDINGS
00022 #  include <boost/numeric/ublas/matrix.hpp> 
00023 #endif 
00024 #include <boost/numeric/bindings/traits/detail/ublas_ordering.hpp>
00025 
00026 #if defined (BOOST_NUMERIC_BINDINGS_FORTRAN) || !defined (BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK)
00027 #  include <boost/static_assert.hpp>
00028 #  include <boost/type_traits/same_traits.hpp>
00029 #endif
00030 
00031 
00032 namespace boost { namespace numeric { namespace bindings { namespace traits {
00033 
00034   // ublas::matrix<>
00035   // Specialization using matrix_detail_traits so that we can specialize for
00036   // matrix_detail_traits< matrix<T, F, ArrT>, matrix<T, F, ArrT> >
00037   // matrix_detail_traits< matrix<T, F, ArrT>, matrix<T, F, ArrT> const >
00038   // at once.
00039   template <typename T, typename F, typename ArrT, typename M>
00040   struct matrix_detail_traits< boost::numeric::ublas::matrix<T, F, ArrT>, M > 
00041   {
00042 #ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
00043     BOOST_STATIC_ASSERT( (boost::is_same<boost::numeric::ublas::matrix<T, F, ArrT>, typename boost::remove_const<M>::type>::value) );
00044 #endif
00045 #ifdef BOOST_NUMERIC_BINDINGS_FORTRAN
00046     BOOST_STATIC_ASSERT((boost::is_same<
00047       typename F::orientation_category, 
00048       boost::numeric::ublas::column_major_tag
00049     >::value)); 
00050 #endif 
00051 
00052     typedef boost::numeric::ublas::matrix<T, F, ArrT>   identifier_type ;
00053     typedef M                                           matrix_type;
00054     typedef general_t                                   matrix_structure; 
00055     typedef typename detail::ublas_ordering<
00056       typename F::orientation_category
00057     >::type                                             ordering_type; 
00058 
00059     typedef T                                           value_type; 
00060     typedef typename detail::generate_const<M,T>::type* pointer; 
00061 
00062       typedef typename identifier_type::orientation_category                      orientation_category; 
00063       typedef typename detail::ublas_ordering<orientation_category>::functor_type functor_t ;
00064 
00065     static pointer storage (matrix_type& m) {
00066       typedef typename detail::generate_const<M,ArrT>::type array_type ;
00067       return vector_traits<array_type>::storage (m.data()); 
00068     }
00069     static int size1 (matrix_type& m) { return m.size1(); } 
00070     static int size2 (matrix_type& m) { return m.size2(); }
00071     static int storage_size (matrix_type& m) { return size1 (m) * size2 (m); }
00072     static int leading_dimension (matrix_type& m) {
00073       // g++ 2.95.4 and 3.0.4 (with -pedantic) dislike 
00074       //   identifier_type::functor_type::size2()
00075       //return functor_t::size_m (m.size1(), m.size2());
00076       return detail::ublas_ordering<orientation_category>::leading_dimension( m ) ;
00077     }
00078 
00079     // stride1 == distance (m (i, j), m (i+1, j)) 
00080     static int stride1 (matrix_type& m) { 
00081       //return functor_t::one1 (m.size1(), m.size2());
00082       return detail::ublas_ordering<orientation_category>::stride1( m ) ;
00083     } 
00084     // stride2 == distance (m (i, j), m (i, j+1)) 
00085     static int stride2 (matrix_type& m) { 
00086       //return functor_t::one2 (m.size1(), m.size2());
00087       return detail::ublas_ordering<orientation_category>::stride2( m ) ;
00088     }
00089   }; 
00090 
00091 
00092   // ublas::matrix_reference<> 
00093   template <typename M, typename MR>
00094   struct matrix_detail_traits<boost::numeric::ublas::matrix_reference<M>, MR >
00095   {
00096 #ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
00097     BOOST_STATIC_ASSERT( (boost::is_same< boost::numeric::ublas::matrix_reference<M>, typename boost::remove_const<MR>::type>::value) ) ;
00098 #endif 
00099 
00100     typedef boost::numeric::ublas::matrix_reference<M>  identifier_type;
00101     typedef MR                                          matrix_type;
00102     typedef typename matrix_traits<M>::matrix_structure matrix_structure; 
00103     typedef typename matrix_traits<M>::ordering_type    ordering_type; 
00104 
00105     typedef typename M::value_type                                value_type;
00106     typedef typename detail::generate_const<MR,value_type>::type* pointer; 
00107 
00108   private:
00109     typedef typename detail::generate_const<MR, M>::type m_type; 
00110 
00111   public:
00112     static pointer storage (matrix_type& mr) {
00113       return matrix_traits<m_type>::storage (mr.expression());
00114     }
00115 
00116     static int size1 (matrix_type& mr) { return mr.size1(); } 
00117     static int size2 (matrix_type& mr) { return mr.size2(); }
00118     static int leading_dimension (matrix_type& mr) {
00119       return matrix_traits<m_type>::leading_dimension (mr.expression()); 
00120     }
00121 
00122     static int stride1 (matrix_type& mr) { 
00123       return matrix_traits<m_type>::stride1 (mr.expression()); 
00124     } 
00125     static int stride2 (matrix_type& mr) { 
00126       return matrix_traits<m_type>::stride2 (mr.expression()); 
00127     }
00128     // Only for banded matrices
00129     static int upper_bandwidth(matrix_type& mr) {
00130       return matrix_traits<m_type>::upper_bandwidth(mr.expression());
00131     }
00132     static int lower_bandwidth(matrix_type& mr) {
00133       return matrix_traits<m_type>::lower_bandwidth(mr.expression());
00134     }
00135   }; 
00136 
00137 
00138   // ublas::matrix_range<> 
00139   template <typename M, typename MR>
00140   struct matrix_detail_traits<boost::numeric::ublas::matrix_range<M>, MR >
00141   {
00142 #ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
00143     BOOST_STATIC_ASSERT( (boost::is_same< boost::numeric::ublas::matrix_range<M>, typename boost::remove_const<MR>::type>::value) ) ;
00144 #endif 
00145 
00146     typedef boost::numeric::ublas::matrix_range<M>      identifier_type;
00147     typedef MR                                          matrix_type;
00148     typedef typename matrix_traits<M>::matrix_structure matrix_structure;
00149     typedef typename matrix_traits<M>::ordering_type    ordering_type; 
00150 
00151   private:
00152     typedef typename detail::generate_const<MR, typename MR::matrix_closure_type>::type m_type; 
00153 
00154   public:
00155     typedef typename matrix_traits<m_type>::value_type            value_type;
00156     typedef typename matrix_traits<m_type>::pointer               pointer ;
00157 
00158   public:
00159     static pointer storage (matrix_type& mr) {
00160       m_type& mt = mr.data(); 
00161       pointer ptr = matrix_traits<m_type>::storage (mt);
00162       ptr += mr.start1() * matrix_traits<m_type>::stride1 (mt); 
00163       ptr += mr.start2() * matrix_traits<m_type>::stride2 (mt); 
00164       return ptr; 
00165     }
00166 
00167     static int size1 (matrix_type& mr) { return mr.size1(); } 
00168     static int size2 (matrix_type& mr) { return mr.size2(); }
00169     static int leading_dimension (matrix_type& mr) {
00170       return matrix_traits<m_type>::leading_dimension (mr.data()); 
00171     }
00172 
00173     static int stride1 (matrix_type& mr) { 
00174       return matrix_traits<m_type>::stride1 (mr.data()); 
00175     } 
00176     static int stride2 (matrix_type& mr) { 
00177       return matrix_traits<m_type>::stride2 (mr.data()); 
00178     }
00179     // For band matrices only
00180     static int upper_bandwidth (matrix_type& mr) {
00181        return matrix_traits<m_type>::upper_bandwidth(mr.data());
00182     }
00183     static int lower_bandwidth (matrix_type& mr) {
00184        return matrix_traits<m_type>::lower_bandwidth(mr.data());
00185     }
00186   }; 
00187 
00188 
00189   // ublas::matrix_slice<> 
00190   template <typename M, typename MS>
00191   struct matrix_detail_traits<boost::numeric::ublas::matrix_slice<M>, MS > 
00192   {
00193 #ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
00194     BOOST_STATIC_ASSERT( (boost::is_same< boost::numeric::ublas::matrix_slice<M>, typename boost::remove_const<MS>::type>::value) ) ;
00195 #endif 
00196 
00197     typedef boost::numeric::ublas::matrix_slice<M>   identifier_type;
00198     typedef MS                                       matrix_type;
00199     typedef unknown_structure_t                      matrix_structure; 
00200     typedef typename matrix_traits<M>::ordering_type ordering_type; 
00201 
00202     typedef typename M::value_type                                value_type;
00203     typedef typename detail::generate_const<MS,value_type>::type* pointer; 
00204 
00205   private:
00206     typedef typename detail::generate_const<MS, typename MS::matrix_closure_type>::type m_type; 
00207 
00208   public:
00209     static pointer storage (matrix_type& ms) {
00210       m_type& mt = ms.data(); 
00211       pointer ptr = matrix_traits<M>::storage (mt);
00212       ptr += ms.start1() * matrix_traits<M>::stride1 (mt); 
00213       ptr += ms.start2() * matrix_traits<M>::stride2 (mt); 
00214       return ptr; 
00215     }
00216 
00217     static int size1 (matrix_type& ms) { return ms.size1(); } 
00218     static int size2 (matrix_type& ms) { return ms.size2(); }
00219 
00220   private:
00221     static int ld (int s1, int s2, boost::numeric::ublas::row_major_tag) {
00222       return s1; 
00223     }
00224     static int ld (int s1, int s2, boost::numeric::ublas::column_major_tag) {
00225       return s2; 
00226     }
00227   public:
00228     static int leading_dimension (matrix_type& ms) {
00229       typedef typename identifier_type::orientation_category oc_t; 
00230       return ld (ms.stride1(), ms.stride2(), oc_t())
00231         * matrix_traits<m_type>::leading_dimension (ms.data()); 
00232     }
00233 
00234     static int stride1 (matrix_type& ms) { 
00235       return ms.stride1() * matrix_traits<m_type>::stride1 (ms.data()); 
00236     } 
00237     static int stride2 (matrix_type& ms) { 
00238       return ms.stride2() * matrix_traits<m_type>::stride2 (ms.data()); 
00239     }
00240 
00241   }; 
00242 
00243 
00244   // matrix_row<> and matrix_column<> are vectors:
00245 
00246   // ublas::matrix_row<>
00247   template <typename M, typename MR>
00248   struct vector_detail_traits< boost::numeric::ublas::matrix_row<M>, MR > 
00249   : default_vector_traits< MR, typename M::value_type > 
00250   {
00251 #ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
00252     BOOST_STATIC_ASSERT( (boost::is_same< boost::numeric::ublas::matrix_row<M>, typename boost::remove_const<MR>::type>::value) ) ;
00253 #endif 
00254 
00255     typedef boost::numeric::ublas::matrix_row<M>                   identifier_type;
00256     typedef MR                                                     vector_type;
00257     typedef typename M::value_type                                 value_type;
00258     typedef typename default_vector_traits<MR,value_type>::pointer pointer; 
00259 
00260   private:
00261     typedef typename detail::generate_const<MR, typename MR::matrix_closure_type>::type m_type; 
00262 
00263   public:
00264     static pointer storage (vector_type& mr) {
00265       m_type& mt = mr.data(); 
00266       pointer ptr = matrix_traits<m_type>::storage (mt); 
00267       ptr += mr.index() * matrix_traits<m_type>::stride1 (mt);
00268       return ptr; 
00269     }
00270     static int stride (vector_type& mr) { 
00271       return matrix_traits<m_type>::stride2 (mr.data());
00272     } 
00273   }; 
00274 
00275 
00276   // ublas::matrix_column<>
00277   template <typename M, typename MC>
00278   struct vector_detail_traits< boost::numeric::ublas::matrix_column<M>, MC > 
00279   : default_vector_traits< MC, typename M::value_type > 
00280   {
00281 #ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
00282     BOOST_STATIC_ASSERT( (boost::is_same< boost::numeric::ublas::matrix_column<M>, typename boost::remove_const<MC>::type>::value) ) ;
00283 #endif 
00284 
00285     typedef boost::numeric::ublas::matrix_column<M>                identifier_type; 
00286     typedef MC                                                     vector_type;
00287     typedef typename M::value_type                                 value_type ;
00288     typedef typename default_vector_traits<MC,value_type>::pointer pointer; 
00289 
00290   private:
00291     typedef typename detail::generate_const<MC, typename MC::matrix_closure_type>::type m_type; 
00292 
00293   public:
00294     static pointer storage (vector_type& mc) {
00295       m_type& mt = mc.data(); 
00296       pointer ptr = matrix_traits<m_type>::storage (mt); 
00297       ptr += mc.index() * matrix_traits<m_type>::stride2 (mt);
00298       return ptr; 
00299     }
00300     static int stride (vector_type& mc) { 
00301       return matrix_traits<m_type>::stride1 (mc.data());
00302     } 
00303   }; 
00304 
00305 
00306 #ifndef BOOST_NUMERIC_BINDINGS_FORTRAN 
00307   
00308   // (undocumented) ublas::c_matrix<> 
00309   template <typename T, std::size_t M, std::size_t N, typename Matr>
00310   struct matrix_detail_traits< boost::numeric::ublas::c_matrix<T,M,N>, Matr > 
00311   {
00312 #ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
00313     BOOST_STATIC_ASSERT( (boost::is_same<boost::numeric::ublas::c_matrix<T,M,N>, typename boost::remove_const<Matr>::type>::value) );
00314 #endif
00315 
00316     typedef boost::numeric::ublas::c_matrix<T,M,N>   identifier_type ;
00317     typedef Matr                                     matrix_type;
00318     typedef general_t                                matrix_structure; 
00319     typedef row_major_t                              ordering_type; 
00320 
00321     typedef T                                              value_type; 
00322     typedef typename detail::generate_const<Matr,T>::type* pointer; 
00323 
00324     static pointer storage (matrix_type& m) { return m.data(); }
00325     static int size1 (matrix_type& m) { return m.size1(); } 
00326     static int size2 (matrix_type& m) { return m.size2(); }
00327     static int storage_size (matrix_type& m) { return M * N; }
00328     static int leading_dimension (matrix_type& m) { return N; }
00329 
00330     // stride1 == distance (m (i, j), m (i+1, j)) 
00331     static int stride1 (matrix_type& m) { return N; }
00332     // stride2 == distance (m (i, j), m (i, j+1)) 
00333     static int stride2 (matrix_type& m) { return 1; }
00334   }; 
00335 
00336 #endif // BOOST_NUMERIC_BINDINGS_FORTRAN 
00337 
00338 
00339   // TO DO: matrix_vector_range<>, matrix_vector_slice<> 
00340 
00341 }}}}
00342 
00343 #endif // BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS 
00344 
00345 #endif // BOOST_NUMERIC_BINDINGS_TRAITS_UBLAS_MATRIX_H

Generated on Wed Nov 23 19:00:52 2011 for FreeCAD by  doxygen 1.6.1