![]() |
Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms
|
00001 // 00002 // Copyright (c) 2010 Athanasios Iliopoulos 00003 // 00004 // Distributed under the Boost Software License, Version 1.0. (See 00005 // accompanying file LICENSE_1_0.txt or copy at 00006 // http://www.boost.org/LICENSE_1_0.txt) 00007 // 00008 00009 #ifndef ASSIGNMENT_HPP 00010 #define ASSIGNMENT_HPP 00011 #include <boost/numeric/ublas/vector_expression.hpp> 00012 #include <boost/numeric/ublas/matrix_expression.hpp> 00013 00018 namespace boost { namespace numeric { namespace ublas { 00019 00024 template <class TV> 00025 class index_manipulator { 00026 public: 00027 typedef TV type; 00028 BOOST_UBLAS_INLINE 00029 const type &operator () () const { 00030 return *static_cast<const type *> (this); 00031 } 00032 BOOST_UBLAS_INLINE 00033 type &operator () () { 00034 return *static_cast<type *> (this); 00035 } 00036 }; 00037 00045 template <typename T> 00046 class vector_move_to_manip: public index_manipulator<vector_move_to_manip<T> > { 00047 public: 00048 BOOST_UBLAS_INLINE 00049 vector_move_to_manip(const T &k): i(k) { } 00050 00051 template <typename V> 00052 BOOST_UBLAS_INLINE 00053 void manip(V &k) const { k=i; } 00054 private: 00055 T i; 00056 }; 00057 00076 template <typename T> 00077 BOOST_UBLAS_INLINE vector_move_to_manip<T> move_to(T i) { 00078 return vector_move_to_manip<T>(i); 00079 } 00080 00088 template <std::size_t I> 00089 class static_vector_move_to_manip: public index_manipulator<static_vector_move_to_manip<I> > { 00090 public: 00091 template <typename V> 00092 BOOST_UBLAS_INLINE 00093 void manip(V &k) const { k=I; } 00094 }; 00095 00115 template <std::size_t I> 00116 BOOST_UBLAS_INLINE static_vector_move_to_manip<I> move_to() { 00117 return static_vector_move_to_manip<I>(); 00118 } 00119 00127 template <typename T> 00128 class vector_move_manip: public index_manipulator<vector_move_manip<T> > { 00129 public: 00130 BOOST_UBLAS_INLINE 00131 vector_move_manip(const T &k): i(k) { } 00132 00133 template <typename V> 00134 BOOST_UBLAS_INLINE void manip(V &k) const { k+=i; } 00135 private: 00136 T i; 00137 }; 00138 00158 template <typename T> 00159 BOOST_UBLAS_INLINE vector_move_manip<T> move(T i) { 00160 return vector_move_manip<T>(i); 00161 } 00162 00173 template <std::size_t I> 00174 class static_vector_move_manip: public index_manipulator<static_vector_move_manip<I> > { 00175 public: 00176 template <typename V> 00177 BOOST_UBLAS_INLINE void manip(V &k) const { k+=I; } 00178 }; 00179 00201 template <std::size_t I> 00202 BOOST_UBLAS_INLINE static_vector_move_manip<I> move() { 00203 return static_vector_move_manip<I>(); 00204 } 00205 00216 template <typename T> 00217 class matrix_move_to_manip: public index_manipulator<matrix_move_to_manip<T> > { 00218 public: 00219 BOOST_UBLAS_INLINE 00220 matrix_move_to_manip(T k, T l): i(k), j(l) { } 00221 00222 template <typename V1, typename V2> 00223 BOOST_UBLAS_INLINE 00224 void manip(V1 &k, V2 &l) const { 00225 k=i; 00226 l=j; 00227 } 00228 private: 00229 T i, j; 00230 }; 00231 00257 template <typename T> 00258 BOOST_UBLAS_INLINE matrix_move_to_manip<T> move_to(T i, T j) { 00259 return matrix_move_to_manip<T>(i, j); 00260 } 00261 00262 00272 template <std::size_t I, std::size_t J> 00273 class static_matrix_move_to_manip: public index_manipulator<static_matrix_move_to_manip<I, J> > { 00274 public: 00275 template <typename V, typename K> 00276 BOOST_UBLAS_INLINE 00277 void manip(V &k, K &l) const { 00278 k=I; 00279 l=J; 00280 } 00281 }; 00282 00305 template <std::size_t I, std::size_t J> 00306 BOOST_UBLAS_INLINE static_matrix_move_to_manip<I, J> move_to() { 00307 return static_matrix_move_to_manip<I, J>(); 00308 } 00309 00318 template <typename T> 00319 class matrix_move_manip: public index_manipulator<matrix_move_manip<T> > { 00320 public: 00321 BOOST_UBLAS_INLINE 00322 matrix_move_manip(T k, T l): i(k), j(l) { } 00323 00324 template <typename V, typename K> 00325 BOOST_UBLAS_INLINE 00326 void manip(V &k, K &l) const { 00327 k+=i; 00328 l+=j; 00329 } 00330 private: 00331 T i, j; 00332 }; 00333 00357 template <typename T> 00358 BOOST_UBLAS_INLINE matrix_move_manip<T> move(T i, T j) { 00359 return matrix_move_manip<T>(i, j); 00360 } 00361 00372 template <std::size_t I, std::size_t J> 00373 class static_matrix_move_manip: public index_manipulator<static_matrix_move_manip<I, J> > { 00374 public: 00375 template <typename V, typename K> 00376 BOOST_UBLAS_INLINE 00377 void manip(V &k, K &l) const { 00378 k+=I; 00379 l+=J; 00380 } 00381 }; 00382 00410 template <std::size_t I, std::size_t J> 00411 BOOST_UBLAS_INLINE static_matrix_move_manip<I, J> move() { 00412 return static_matrix_move_manip<I, J>(); 00413 } 00414 00423 class begin1_manip: public index_manipulator<begin1_manip > { 00424 public: 00425 template <typename V, typename K> 00426 BOOST_UBLAS_INLINE 00427 void manip(V & k, K &/*l*/) const { 00428 k=0; 00429 } 00430 }; 00431 00454 inline begin1_manip begin1() { 00455 return begin1_manip(); 00456 } 00457 00467 class begin2_manip: public index_manipulator<begin2_manip > { 00468 public: 00469 template <typename V, typename K> 00470 BOOST_UBLAS_INLINE 00471 void manip(V &/*k*/, K &l) const { 00472 l=0; 00473 } 00474 }; 00475 00498 inline begin2_manip begin2() { 00499 return begin2_manip(); 00500 } 00501 00502 00511 class next_row_manip: public index_manipulator<next_row_manip> { 00512 public: 00513 template <typename V, typename K> 00514 BOOST_UBLAS_INLINE 00515 void manip(V &k, K &l) const { 00516 k++; 00517 l=0; 00518 } 00519 }; 00520 00543 inline next_row_manip next_row() { 00544 return next_row_manip(); 00545 } 00546 00555 class next_column_manip: public index_manipulator<next_column_manip> { 00556 public: 00557 template <typename V, typename K> 00558 BOOST_UBLAS_INLINE 00559 void manip(V &k, K &l) const { 00560 k=0; 00561 l++; 00562 } 00563 }; 00564 00587 inline next_column_manip next_column() { 00588 return next_column_manip(); 00589 } 00590 00595 template <class T> 00596 class fill_policy_wrapper { 00597 public: 00598 typedef T type; 00599 }; 00600 00601 // Collection of the fill policies 00602 namespace fill_policy { 00603 00612 class index_assign :public fill_policy_wrapper<index_assign> { 00613 public: 00614 template <class T, typename S, typename V> 00615 BOOST_UBLAS_INLINE 00616 static void apply(T &e, const S &i, const V &v) { 00617 e()(i) = v; 00618 } 00619 template <class T, typename S, typename V> 00620 BOOST_UBLAS_INLINE 00621 static void apply(T &e, const S &i, const S &j, const V &v) { 00622 e()(i, j) = v; 00623 } 00624 }; 00625 00634 class index_plus_assign :public fill_policy_wrapper<index_plus_assign> { 00635 public: 00636 template <class T, typename S, typename V> 00637 BOOST_UBLAS_INLINE 00638 static void apply(T &e, const S &i, const V &v) { 00639 e()(i) += v; 00640 } 00641 template <class T, typename S, typename V> 00642 BOOST_UBLAS_INLINE 00643 static void apply(T &e, const S &i, const S &j, const V &v) { 00644 e()(i, j) += v; 00645 } 00646 }; 00647 00656 class index_minus_assign :public fill_policy_wrapper<index_minus_assign> { 00657 public: 00658 template <class T, typename S, typename V> 00659 BOOST_UBLAS_INLINE 00660 static void apply(T &e, const S &i, const V &v) { 00661 e()(i) -= v; 00662 } 00663 template <class T, typename S, typename V> 00664 BOOST_UBLAS_INLINE 00665 static void apply(T &e, const S &i, const S &j, const V &v) { 00666 e()(i, j) -= v; 00667 } 00668 }; 00669 00679 class sparse_push_back :public fill_policy_wrapper<sparse_push_back > { 00680 public: 00681 template <class T, class S, class V> 00682 BOOST_UBLAS_INLINE 00683 static void apply(T &e, const S &i, const V &v) { 00684 e().push_back(i, v); 00685 } 00686 template <class T, class S, class V> 00687 BOOST_UBLAS_INLINE 00688 static void apply(T &e, const S &i, const S &j, const V &v) { 00689 e().push_back(i,j, v); 00690 } 00691 }; 00692 00700 class sparse_insert :public fill_policy_wrapper<sparse_insert> { 00701 public: 00702 template <class T, class S, class V> 00703 BOOST_UBLAS_INLINE 00704 static void apply(T &e, const S &i, const V &v) { 00705 e().insert_element(i, v); 00706 } 00707 template <class T, class S, class V> 00708 BOOST_UBLAS_INLINE 00709 static void apply(T &e, const S &i, const S &j, const V &v) { 00710 e().insert_element(i,j, v); 00711 } 00712 }; 00713 00714 } 00715 00719 template <class T> 00720 class traverse_policy_wrapper { 00721 public: 00722 typedef T type; 00723 }; 00724 00725 // Collection of the traverse policies 00726 namespace traverse_policy { 00727 00728 00734 struct no_wrap { 00738 template <class S1, class S2, class S3> 00739 BOOST_UBLAS_INLINE 00740 static void apply1(const S1 &/*s*/, S2 &/*i*/, S3 &/*j*/) { 00741 } 00742 00746 template <class S1, class S2, class S3> 00747 BOOST_UBLAS_INLINE 00748 static void apply2(const S1 &/*s1*/, const S1 &/*s2*/, S2 &/*i1*/, S3 &/*i2*/) { 00749 } 00750 }; 00751 00757 struct wrap { 00761 template <class S1, class S2, class S3> 00762 BOOST_UBLAS_INLINE 00763 static void apply1(const S1 &s, S2 &i1, S3 &i2) { 00764 if (i2>=s) { 00765 i1++; 00766 i2=0; 00767 } 00768 } 00769 00773 template <class S1, class S2, class S3> 00774 BOOST_UBLAS_INLINE 00775 static void apply2(const S1 &s1, const S1 &s2, S2 &i1, S3 &i2) { 00776 if (i2>=s2) i2=0; // Wrap to the next block 00777 else i1-=s1; // Move up (or right) one block 00778 } 00779 }; 00780 00794 template <class Wrap = wrap> 00795 class by_row_policy :public traverse_policy_wrapper<by_row_policy<Wrap> > { 00796 public: 00797 template <typename S1, typename S2> 00798 BOOST_UBLAS_INLINE 00799 static void advance(S1 &/*i*/, S2 &j) { j++;} 00800 00801 template <class E1, class E2, typename S1, typename S2, typename S3, typename S4, typename S5> 00802 BOOST_UBLAS_INLINE 00803 static bool next(const E1 &e, const E2 &me, S1 &i, S2 &j, const S3 &/*i0*/, const S3 &j0, S4 &k, S5 &l) { 00804 l++; j++; 00805 if (l>=e().size2()) { 00806 l=0; k++; j=j0; i++; 00807 // It is assumed that the iteration starts from 0 and happens only using this function from within 00808 // an assigner object. 00809 // Otherwise (i.e. if it is called outside the assigner object) apply2 should have been 00810 // outside the if statement. 00811 if (k>=e().size1()) { 00812 j=j0+e().size2(); 00813 Wrap::apply2(e().size1(), me().size2(), i, j); 00814 return false; 00815 } 00816 } 00817 return true; 00818 } 00819 00820 template <class E, typename S1, typename S2> 00821 BOOST_UBLAS_INLINE 00822 static void apply_wrap(const E& e, S1 &i, S2 &j) { 00823 Wrap::apply1(e().size2(), i, j); 00824 } 00825 }; 00826 00840 template <class Wrap = wrap> 00841 class by_column_policy :public traverse_policy_wrapper<by_column_policy<Wrap> > { 00842 public: 00843 template <typename S1, typename S2> 00844 BOOST_UBLAS_INLINE 00845 static void advance(S1 &i, S2 &/*j*/) { i++;} 00846 00847 template <class E1, class E2, typename S1, typename S2, typename S3, typename S4, typename S5> 00848 BOOST_UBLAS_INLINE 00849 static bool next(const E1 &e, const E2 &me, S1 &i, S2 &j, const S3 &i0, const S3 &/*j0*/, S4 &k, S5 &l) { 00850 k++; i++; 00851 if (k>=e().size1()) { 00852 k=0; l++; i=i0; j++; 00853 // It is assumed that the iteration starts from 0 and happens only using this function from within 00854 // an assigner object. 00855 // Otherwise (i.e. if it is called outside the assigner object) apply2 should have been 00856 // outside the if statement. 00857 if (l>=e().size2()) { 00858 i=i0+e().size1(); 00859 Wrap::apply2(e().size2(), me().size1(), j, i); 00860 return false; 00861 } 00862 } 00863 return true; 00864 } 00865 00866 template <class E, typename S1, typename S2> 00867 BOOST_UBLAS_INLINE 00868 static void apply_wrap(const E& e, S1 &i, S2 &j) { 00869 Wrap::apply1(e().size1(), j, i); 00870 } 00871 }; 00872 } 00873 #ifndef BOOST_UBLAS_DEFAULT_NO_WRAP_POLICY 00874 typedef traverse_policy::wrap DEFAULT_WRAP_POLICY; 00875 #else 00876 typedef traverse_policy::no_wrap DEFAULT_WRAP_POLICY; 00877 #endif 00878 00879 #ifndef BOOST_UBLAS_DEFAULT_ASSIGN_BY_COLUMN 00880 typedef traverse_policy::by_row_policy<DEFAULT_WRAP_POLICY> DEFAULT_TRAVERSE_POLICY; 00881 #else 00882 typedef traverse_policy::by_column<DEFAULT_WRAP_POLICY> DEFAULT_TRAVERSE_POLICY; 00883 #endif 00884 00885 // Traverse policy namespace 00886 namespace traverse_policy { 00887 00888 inline by_row_policy<DEFAULT_WRAP_POLICY> by_row() { 00889 return by_row_policy<DEFAULT_WRAP_POLICY>(); 00890 } 00891 00892 inline by_row_policy<wrap> by_row_wrap() { 00893 return by_row_policy<wrap>(); 00894 } 00895 00896 inline by_row_policy<no_wrap> by_row_no_wrap() { 00897 return by_row_policy<no_wrap>(); 00898 } 00899 00900 inline by_column_policy<DEFAULT_WRAP_POLICY> by_column() { 00901 return by_column_policy<DEFAULT_WRAP_POLICY>(); 00902 } 00903 00904 inline by_column_policy<wrap> by_column_wrap() { 00905 return by_column_policy<wrap>(); 00906 } 00907 00908 inline by_column_policy<no_wrap> by_column_no_wrap() { 00909 return by_column_policy<no_wrap>(); 00910 } 00911 00912 } 00913 00922 template <class E, class Fill_Policy = fill_policy::index_assign> 00923 class vector_expression_assigner { 00924 public: 00925 typedef typename E::expression_type::value_type value_type; 00926 typedef typename E::expression_type::size_type size_type; 00927 00928 BOOST_UBLAS_INLINE 00929 vector_expression_assigner(E &e):ve(e), i(0) { 00930 } 00931 00932 BOOST_UBLAS_INLINE 00933 vector_expression_assigner(size_type k, E &e):ve(e), i(k) { 00934 // Overloaded like that so it can be differentiated from (E, val). 00935 // Otherwise there would be an ambiquity when value_type == size_type. 00936 } 00937 00938 BOOST_UBLAS_INLINE 00939 vector_expression_assigner(E &e, value_type val):ve(e), i(0) { 00940 operator,(val); 00941 } 00942 00943 template <class AE> 00944 BOOST_UBLAS_INLINE 00945 vector_expression_assigner(E &e, const vector_expression<AE> &nve):ve(e), i(0) { 00946 operator,(nve); 00947 } 00948 00949 template <typename T> 00950 BOOST_UBLAS_INLINE 00951 vector_expression_assigner(E &e, const index_manipulator<T> &ta):ve(e), i(0) { 00952 operator,(ta); 00953 } 00954 00955 BOOST_UBLAS_INLINE 00956 vector_expression_assigner &operator, (const value_type& val) { 00957 apply(val); 00958 return *this; 00959 } 00960 00961 template <class AE> 00962 BOOST_UBLAS_INLINE 00963 vector_expression_assigner &operator, (const vector_expression<AE> &nve) { 00964 for (typename AE::size_type k = 0; k!= nve().size(); k++) 00965 operator,(nve()(k)); 00966 return *this; 00967 } 00968 00969 template <typename T> 00970 BOOST_UBLAS_INLINE 00971 vector_expression_assigner &operator, (const index_manipulator<T> &ta) { 00972 ta().manip(i); 00973 return *this; 00974 } 00975 00976 template <class T> 00977 BOOST_UBLAS_INLINE 00978 vector_expression_assigner<E, T> operator, (fill_policy_wrapper<T>) const { 00979 return vector_expression_assigner<E, T>(i, ve); 00980 } 00981 00982 private: 00983 BOOST_UBLAS_INLINE 00984 vector_expression_assigner &apply(const typename E::expression_type::value_type& val) { 00985 Fill_Policy::apply(ve, i++, val); 00986 return *this; 00987 } 00988 00989 private: 00990 E &ve; 00991 size_type i; 00992 }; 00993 00994 /* 00995 // The following static assigner is about 30% slower than the dynamic one, probably due to the recursive creation of assigner objects. 00996 // It remains commented here for future reference. 00997 00998 template <class E, std::size_t I=0> 00999 class static_vector_expression_assigner { 01000 public: 01001 typedef typename E::expression_type::value_type value_type; 01002 typedef typename E::expression_type::size_type size_type; 01003 01004 BOOST_UBLAS_INLINE 01005 static_vector_expression_assigner(E &e):ve(e) { 01006 } 01007 01008 BOOST_UBLAS_INLINE 01009 static_vector_expression_assigner(E &e, value_type val):ve(e) { 01010 operator,(val); 01011 } 01012 01013 BOOST_UBLAS_INLINE 01014 static_vector_expression_assigner<E, I+1> operator, (const value_type& val) { 01015 return apply(val); 01016 } 01017 01018 private: 01019 BOOST_UBLAS_INLINE 01020 static_vector_expression_assigner<E, I+1> apply(const typename E::expression_type::value_type& val) { 01021 ve()(I)=val; 01022 return static_vector_expression_assigner<E, I+1>(ve); 01023 } 01024 01025 private: 01026 E &ve; 01027 }; 01028 01029 template <class E> 01030 BOOST_UBLAS_INLINE 01031 static_vector_expression_assigner<vector_expression<E>, 1 > test_static(vector_expression<E> &v, const typename E::value_type &val) { 01032 v()(0)=val; 01033 return static_vector_expression_assigner<vector_expression<E>, 1 >(v); 01034 } 01035 */ 01036 01037 01045 template <class E> 01046 BOOST_UBLAS_INLINE 01047 vector_expression_assigner<vector_expression<E> > operator<<=(vector_expression<E> &v, const typename E::value_type &val) { 01048 return vector_expression_assigner<vector_expression<E> >(v,val); 01049 } 01050 01058 template <class E1, class E2> 01059 BOOST_UBLAS_INLINE 01060 vector_expression_assigner<vector_expression<E1> > operator<<=(vector_expression<E1> &v, const vector_expression<E2> &ve) { 01061 return vector_expression_assigner<vector_expression<E1> >(v,ve); 01062 } 01063 01071 template <class E, typename T> 01072 BOOST_UBLAS_INLINE 01073 vector_expression_assigner<vector_expression<E> > operator<<=(vector_expression<E> &v, const index_manipulator<T> &nv) { 01074 return vector_expression_assigner<vector_expression<E> >(v,nv); 01075 } 01076 01084 template <class E, typename T> 01085 BOOST_UBLAS_INLINE 01086 vector_expression_assigner<vector_expression<E>, T> operator<<=(vector_expression<E> &v, fill_policy_wrapper<T>) { 01087 return vector_expression_assigner<vector_expression<E>, T>(v); 01088 } 01089 01098 template <class E, class Fill_Policy = fill_policy::index_assign, class Traverse_Policy = DEFAULT_TRAVERSE_POLICY > 01099 class matrix_expression_assigner { 01100 public: 01101 typedef typename E::expression_type::size_type size_type; 01102 01103 BOOST_UBLAS_INLINE 01104 matrix_expression_assigner(E &e): me(e), i(0), j(0) { 01105 } 01106 01107 BOOST_UBLAS_INLINE 01108 matrix_expression_assigner(E &e, size_type k, size_type l): me(e), i(k), j(l) { 01109 } 01110 01111 BOOST_UBLAS_INLINE 01112 matrix_expression_assigner(E &e, typename E::expression_type::value_type val): me(e), i(0), j(0) { 01113 operator,(val); 01114 } 01115 01116 template <class AE> 01117 BOOST_UBLAS_INLINE 01118 matrix_expression_assigner(E &e, const vector_expression<AE> &nve):me(e), i(0), j(0) { 01119 operator,(nve); 01120 } 01121 01122 template <class AE> 01123 BOOST_UBLAS_INLINE 01124 matrix_expression_assigner(E &e, const matrix_expression<AE> &nme):me(e), i(0), j(0) { 01125 operator,(nme); 01126 } 01127 01128 template <typename T> 01129 BOOST_UBLAS_INLINE 01130 matrix_expression_assigner(E &e, const index_manipulator<T> &ta):me(e), i(0), j(0) { 01131 operator,(ta); 01132 } 01133 01134 BOOST_UBLAS_INLINE 01135 matrix_expression_assigner &operator, (const typename E::expression_type::value_type& val) { 01136 Traverse_Policy::apply_wrap(me, i ,j); 01137 return apply(val); 01138 } 01139 01140 template <class AE> 01141 BOOST_UBLAS_INLINE 01142 matrix_expression_assigner &operator, (const vector_expression<AE> &nve) { 01143 for (typename AE::size_type k = 0; k!= nve().size(); k++) { 01144 operator,(nve()(k)); 01145 } 01146 return *this; 01147 } 01148 01149 template <class AE> 01150 BOOST_UBLAS_INLINE 01151 matrix_expression_assigner &operator, (const matrix_expression<AE> &nme) { 01152 return apply(nme); 01153 } 01154 01155 template <typename T> 01156 BOOST_UBLAS_INLINE 01157 matrix_expression_assigner &operator, (const index_manipulator<T> &ta) { 01158 ta().manip(i, j); 01159 return *this; 01160 } 01161 01162 template <class T> 01163 BOOST_UBLAS_INLINE 01164 matrix_expression_assigner<E, T, Traverse_Policy> operator, (fill_policy_wrapper<T>) const { 01165 return matrix_expression_assigner<E, T, Traverse_Policy>(me, i, j); 01166 } 01167 01168 01169 template <class T> 01170 BOOST_UBLAS_INLINE 01171 matrix_expression_assigner<E, Fill_Policy, T> operator, (traverse_policy_wrapper<T>) { 01172 Traverse_Policy::apply_wrap(me, i ,j); 01173 return matrix_expression_assigner<E, Fill_Policy, T>(me, i, j); 01174 } 01175 01176 private: 01177 BOOST_UBLAS_INLINE 01178 matrix_expression_assigner &apply(const typename E::expression_type::value_type& val) { 01179 Fill_Policy::apply(me, i, j, val); 01180 Traverse_Policy::advance(i,j); 01181 return *this; 01182 } 01183 01184 template <class AE> 01185 BOOST_UBLAS_INLINE 01186 matrix_expression_assigner &apply(const matrix_expression<AE> &nme) { 01187 size_type bi = i; 01188 size_type bj = j; 01189 typename AE::size_type k=0, l=0; 01190 Fill_Policy::apply(me, i, j, nme()(k, l)); 01191 while (Traverse_Policy::next(nme, me, i, j, bi, bj, k, l)) 01192 Fill_Policy::apply(me, i, j, nme()(k, l)); 01193 return *this; 01194 } 01195 01196 private: 01197 E &me; 01198 size_type i, j; 01199 }; 01200 01208 template <class E> 01209 BOOST_UBLAS_INLINE 01210 matrix_expression_assigner<matrix_expression<E> > operator<<=(matrix_expression<E> &me, const typename E::value_type &val) { 01211 return matrix_expression_assigner<matrix_expression<E> >(me,val); 01212 } 01213 01221 template <class E, typename T> 01222 BOOST_UBLAS_INLINE 01223 matrix_expression_assigner<matrix_expression<E>, T> operator<<=(matrix_expression<E> &me, fill_policy_wrapper<T>) { 01224 return matrix_expression_assigner<matrix_expression<E>, T>(me); 01225 } 01226 01234 template <class E, typename T> 01235 BOOST_UBLAS_INLINE 01236 matrix_expression_assigner<matrix_expression<E> > operator<<=(matrix_expression<E> &me, const index_manipulator<T> &ta) { 01237 return matrix_expression_assigner<matrix_expression<E> >(me,ta); 01238 } 01239 01247 template <class E, typename T> 01248 BOOST_UBLAS_INLINE 01249 matrix_expression_assigner<matrix_expression<E>, fill_policy::index_assign, T> operator<<=(matrix_expression<E> &me, traverse_policy_wrapper<T>) { 01250 return matrix_expression_assigner<matrix_expression<E>, fill_policy::index_assign, T>(me); 01251 } 01252 01260 template <class E1, class E2> 01261 BOOST_UBLAS_INLINE 01262 matrix_expression_assigner<matrix_expression<E1> > operator<<=(matrix_expression<E1> &me, const vector_expression<E2> &ve) { 01263 return matrix_expression_assigner<matrix_expression<E1> >(me,ve); 01264 } 01265 01273 template <class E1, class E2> 01274 BOOST_UBLAS_INLINE 01275 matrix_expression_assigner<matrix_expression<E1> > operator<<=(matrix_expression<E1> &me1, const matrix_expression<E2> &me2) { 01276 return matrix_expression_assigner<matrix_expression<E1> >(me1,me2); 01277 } 01278 01279 } } } 01280 01281 #endif // ASSIGNMENT_HPP