Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms

assignment.hpp

Go to the documentation of this file.
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