- Main Page
- Related Pages
- Classes
- Files

- File List

# assignment.hpp

    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
    00019 namespace boost { namespace numeric { namespace ublas {
    00020
    00026 template <class TV>
    00027 class index_manipulator {
    00028 public:
    00029     typedef TV type;
    00030     BOOST_UBLAS_INLINE
    00031     const type &operator () () const {
    00032         return *static_cast<const type *> (this);
    00033     }
    00034     BOOST_UBLAS_INLINE
    00035     type &operator () () {
    00036         return *static_cast<type *> (this);
    00037     }
    00038 };
    00039
    00048 template <typename T>
    00049 class vector_move_to_manip: public index_manipulator<vector_move_to_manip<T> > {
    00050 public:
    00051     BOOST_UBLAS_INLINE
    00052     vector_move_to_manip(const T &k): i(k) { }
    00053
    00054     template <typename V>
    00055     BOOST_UBLAS_INLINE
    00056     void manip(V &k) const { k=i; }
    00057 private:
    00058     T i;
    00059 };
    00060
    00081 template <typename T>
    00082 BOOST_UBLAS_INLINE vector_move_to_manip<T>  move_to(T i) {
    00083     return vector_move_to_manip<T>(i);
    00084 }
    00085
    00094 template <std::size_t I>
    00095 class static_vector_move_to_manip: public index_manipulator<static_vector_move_to_manip<I> > {
    00096 public:
    00097     template <typename V>
    00098     BOOST_UBLAS_INLINE
    00099     void manip(V &k) const { k=I; }
    00100 };
    00101
    00123 template <std::size_t I>
    00124 BOOST_UBLAS_INLINE static_vector_move_to_manip<I>  move_to() {
    00125     return static_vector_move_to_manip<I>();
    00126 }
    00127
    00136 template <typename T>
    00137 class vector_move_manip: public index_manipulator<vector_move_manip<T> > {
    00138 public:
    00139     BOOST_UBLAS_INLINE
    00140     vector_move_manip(const T &k): i(k) { }
    00141
    00142     template <typename V>
    00143     BOOST_UBLAS_INLINE void manip(V &k) const { k+=i; }
    00144 private:
    00145     T i;
    00146 };
    00147
    00167 template <typename T>
    00168 BOOST_UBLAS_INLINE vector_move_manip<T>  move(T i) {
    00169     return vector_move_manip<T>(i);
    00170 }
    00171
    00182 template <std::size_t I>
    00183 class static_vector_move_manip: public index_manipulator<static_vector_move_manip<I> > {
    00184 public:
    00185     template <typename V>
    00186     BOOST_UBLAS_INLINE void manip(V &k) const { k+=I; }
    00187 };
    00188
    00210 template <std::size_t I>
    00211 BOOST_UBLAS_INLINE static_vector_move_manip<I>  move() {
    00212     return static_vector_move_manip<I>();
    00213 }
    00214
    00225 template <typename T>
    00226 class matrix_move_to_manip: public index_manipulator<matrix_move_to_manip<T> > {
    00227 public:
    00228     BOOST_UBLAS_INLINE
    00229     matrix_move_to_manip(T k, T l): i(k), j(l) { }
    00230
    00231     template <typename V1, typename V2>
    00232     BOOST_UBLAS_INLINE
    00233     void manip(V1 &k, V2 &l) const {
    00234         k=i;
    00235         l=j;
    00236     }
    00237 private:
    00238     T i, j;
    00239 };
    00240
    00266 template <typename T>
    00267 BOOST_UBLAS_INLINE matrix_move_to_manip<T>  move_to(T i, T j) {
    00268     return matrix_move_to_manip<T>(i, j);
    00269 }
    00270
    00271
    00281 template <std::size_t I, std::size_t J>
    00282 class static_matrix_move_to_manip: public index_manipulator<static_matrix_move_to_manip<I, J> > {
    00283 public:
    00284     template <typename V, typename K>
    00285     BOOST_UBLAS_INLINE
    00286     void manip(V &k, K &l) const {
    00287         k=I;
    00288         l=J;
    00289     }
    00290 };
    00291
    00314 template <std::size_t I, std::size_t J>
    00315 BOOST_UBLAS_INLINE static_matrix_move_to_manip<I, J>  move_to() {
    00316     return static_matrix_move_to_manip<I, J>();
    00317 }
    00318
    00327 template <typename T>
    00328 class matrix_move_manip: public index_manipulator<matrix_move_manip<T> > {
    00329 public:
    00330     BOOST_UBLAS_INLINE
    00331     matrix_move_manip(T k, T l): i(k), j(l) { }
    00332
    00333     template <typename V, typename K>
    00334     BOOST_UBLAS_INLINE
    00335     void manip(V &k, K &l) const {
    00336         k+=i;
    00337         l+=j;
    00338     }
    00339 private:
    00340     T i, j;
    00341 };
    00342
    00366 template <typename T>
    00367 BOOST_UBLAS_INLINE matrix_move_manip<T>  move(T i, T j) {
    00368     return matrix_move_manip<T>(i, j);
    00369 }
    00370
    00381 template <std::size_t I, std::size_t J>
    00382 class static_matrix_move_manip: public index_manipulator<static_matrix_move_manip<I, J> > {
    00383 public:
    00384     template <typename V, typename K>
    00385     BOOST_UBLAS_INLINE
    00386     void manip(V &k, K &l) const {
    00387         k+=I;
    00388         l+=J;
    00389     }
    00390 };
    00391
    00419 template <std::size_t I, std::size_t J>
    00420 BOOST_UBLAS_INLINE static_matrix_move_manip<I, J>  move() {
    00421     return static_matrix_move_manip<I, J>();
    00422 }
    00423
    00432 class begin1_manip: public index_manipulator<begin1_manip > {
    00433 public:
    00434     template <typename V, typename K>
    00435     BOOST_UBLAS_INLINE
    00436     void manip(V & k, K &/*l*/) const {
    00437         k=0;
    00438     }
    00439 };
    00440
    00463 BOOST_UBLAS_INLINE begin1_manip  begin1() {
    00464     return begin1_manip();
    00465 }
    00466
    00476 class begin2_manip: public index_manipulator<begin2_manip > {
    00477 public:
    00478     template <typename V, typename K>
    00479     BOOST_UBLAS_INLINE
    00480     void manip(V &/*k*/, K &l) const {
    00481         l=0;
    00482     }
    00483 };
    00484
    00507 BOOST_UBLAS_INLINE begin2_manip  begin2() {
    00508     return begin2_manip();
    00509 }
    00510
    00511
    00520 class next_row_manip: public index_manipulator<next_row_manip> {
    00521 public:
    00522     template <typename V, typename K>
    00523     BOOST_UBLAS_INLINE
    00524     void manip(V &k, K &l) const {
    00525         k++;
    00526         l=0;
    00527     }
    00528 };
    00529
    00552 BOOST_UBLAS_INLINE next_row_manip  next_row() {
    00553     return next_row_manip();
    00554 }
    00555
    00564 class next_column_manip: public index_manipulator<next_column_manip> {
    00565 public:
    00566     template <typename V, typename K>
    00567     BOOST_UBLAS_INLINE
    00568     void manip(V &k, K &l) const {
    00569         k=0;
    00570         l++;
    00571     }
    00572 };
    00573
    00596 BOOST_UBLAS_INLINE next_column_manip next_column() {
    00597     return next_column_manip();
    00598 }
    00599
    00604 template <class T>
    00605 class fill_policy_wrapper {
    00606 public:
    00607     typedef T type;
    00608 };
    00609
    00610 // Collection of the fill policies
    00611 namespace fill_policy {
    00612
    00621     class index_assign :public fill_policy_wrapper<index_assign> {
    00622     public:
    00623         template <class T, typename S, typename V>
    00624         BOOST_UBLAS_INLINE
    00625         static void apply(T &e, const S &i, const V &v) {
    00626             e()(i) = v;
    00627         }
    00628         template <class T, typename S, typename V>
    00629         BOOST_UBLAS_INLINE
    00630         static void apply(T &e, const S &i, const S &j, const V &v) {
    00631             e()(i, j) = v;
    00632         }
    00633     };
    00634
    00643     class index_plus_assign :public fill_policy_wrapper<index_plus_assign> {
    00644     public:
    00645         template <class T, typename S, typename V>
    00646         BOOST_UBLAS_INLINE
    00647         static void apply(T &e, const S &i, const V &v) {
    00648             e()(i) += v;
    00649         }
    00650         template <class T, typename S, typename V>
    00651         BOOST_UBLAS_INLINE
    00652         static void apply(T &e, const S &i, const S &j, const V &v) {
    00653             e()(i, j) += v;
    00654         }
    00655     };
    00656
    00665     class index_minus_assign :public fill_policy_wrapper<index_minus_assign> {
    00666     public:
    00667         template <class T, typename S, typename V>
    00668         BOOST_UBLAS_INLINE
    00669         static void apply(T &e, const S &i, const V &v) {
    00670             e()(i) -= v;
    00671         }
    00672         template <class T, typename S, typename V>
    00673         BOOST_UBLAS_INLINE
    00674         static void apply(T &e, const S &i, const S &j, const V &v) {
    00675             e()(i, j) -= v;
    00676         }
    00677     };
    00678
    00688     class sparse_push_back :public fill_policy_wrapper<sparse_push_back > {
    00689     public:
    00690         template <class T, class S, class V>
    00691         BOOST_UBLAS_INLINE
    00692         static void apply(T &e, const S &i, const V &v) {
    00693             e().push_back(i, v);
    00694         }
    00695         template <class T, class S, class V>
    00696         BOOST_UBLAS_INLINE
    00697         static void apply(T &e, const S &i, const S &j, const V &v) {
    00698             e().push_back(i,j, v);
    00699         }
    00700     };
    00701
    00709     class sparse_insert :public fill_policy_wrapper<sparse_insert> {
    00710     public:
    00711         template <class T, class S, class V>
    00712         BOOST_UBLAS_INLINE
    00713         static void apply(T &e, const S &i, const V &v) {
    00714             e().insert_element(i, v);
    00715         }
    00716         template <class T, class S, class V>
    00717         BOOST_UBLAS_INLINE
    00718         static void apply(T &e, const S &i, const S &j, const V &v) {
    00719             e().insert_element(i,j, v);
    00720         }
    00721     };
    00722
    00723 }
    00724
    00728 template <class T>
    00729 class traverse_policy_wrapper {
    00730 public:
    00731     typedef T type;
    00732 };
    00733
    00734 // Collection of the traverse policies
    00735 namespace traverse_policy {
    00736
    00737
    00743     struct no_wrap {
    00747         template <class S1, class S2, class S3>
    00748         BOOST_UBLAS_INLINE
    00749         static void apply1(const S1 &/*s*/, S2 &/*i*/, S3 &/*j*/) {
    00750         }
    00751
    00755         template <class S1, class S2, class S3>
    00756         BOOST_UBLAS_INLINE
    00757         static void apply2(const S1 &/*s1*/, const S1 &/*s2*/, S2 &/*i1*/, S3 &/*i2*/) {
    00758         }
    00759     };
    00760
    00766     struct wrap {
    00770         template <class S1, class S2, class S3>
    00771         BOOST_UBLAS_INLINE
    00772         static void apply1(const S1 &s, S2 &i1, S3 &i2) {
    00773             if (i2>=s) {
    00774                 i1++;
    00775                 i2=0;
    00776             }
    00777         }
    00778
    00782         template <class S1, class S2, class S3>
    00783         BOOST_UBLAS_INLINE
    00784         static void apply2(const S1 &s1, const S1 &s2, S2 &i1, S3 &i2) {
    00785             if (i2>=s2) i2=0;   // Wrap to the next block
    00786             else i1-=s1;        // Move up (or right) one block
    00787         }
    00788     };
    00789
    00803     template <class Wrap = wrap>
    00804     class by_row_policy :public traverse_policy_wrapper<by_row_policy<Wrap> > {
    00805     public:
    00806         template <typename S1, typename S2>
    00807         BOOST_UBLAS_INLINE
    00808         static void advance(S1 &/*i*/, S2 &j) { j++;}
    00809
    00810         template <class E1, class E2, typename S1, typename S2, typename S3, typename S4, typename S5>
    00811         BOOST_UBLAS_INLINE
    00812         static bool next(const E1 &e, const E2 &me, S1 &i, S2 &j, const S3 &/*i0*/, const S3 &j0, S4 &k, S5 &l) {
    00813             l++; j++;
    00814             if (l>=e().size2()) {
    00815                 l=0; k++; j=j0; i++;
    00816                 // It is assumed that the iteration starts from 0 and happens only using this function from within
    00817                 // an assigner object.
    00818                 // Otherwise (i.e. if it is called outside the assigner object) apply2 should have been
    00819                 // outside the if statement.
    00820                 if (k>=e().size1()) {
    00821                     j=j0+e().size2();
    00822                     Wrap::apply2(e().size1(), me().size2(), i, j);
    00823                     return false;
    00824                 }
    00825             }
    00826             return true;
    00827         }
    00828
    00829         template <class E, typename S1, typename S2>
    00830         BOOST_UBLAS_INLINE
    00831         static void apply_wrap(const E& e, S1 &i, S2 &j) {
    00832             Wrap::apply1(e().size2(), i, j);
    00833         }
    00834     };
    00835
    00849     template <class Wrap = wrap>
    00850     class by_column_policy :public traverse_policy_wrapper<by_column_policy<Wrap> > {
    00851     public:
    00852         template <typename S1, typename S2>
    00853         BOOST_UBLAS_INLINE
    00854         static void advance(S1 &i, S2 &/*j*/) { i++;}
    00855
    00856         template <class E1, class E2, typename S1, typename S2, typename S3, typename S4, typename S5>
    00857         BOOST_UBLAS_INLINE
    00858         static bool next(const E1 &e, const E2 &me, S1 &i, S2 &j, const S3 &i0, const S3 &/*j0*/, S4 &k, S5 &l) {
    00859             k++; i++;
    00860             if (k>=e().size1()) {
    00861                 k=0; l++; i=i0; j++;
    00862                 // It is assumed that the iteration starts from 0 and happens only using this function from within
    00863                 // an assigner object.
    00864                 // Otherwise (i.e. if it is called outside the assigner object) apply2 should have been
    00865                 // outside the if statement.
    00866                 if (l>=e().size2()) {
    00867                     i=i0+e().size1();
    00868                     Wrap::apply2(e().size2(), me().size1(), j, i);
    00869                     return false;
    00870                 }
    00871             }
    00872             return true;
    00873         }
    00874
    00875         template <class E, typename S1, typename S2>
    00876         BOOST_UBLAS_INLINE
    00877         static void apply_wrap(const E& e, S1 &i, S2 &j) {
    00878             Wrap::apply1(e().size1(), j, i);
    00879         }
    00880     };
    00881 }
    00882 #ifndef BOOST_UBLAS_DEFAULT_NO_WRAP_POLICY
    00883     typedef traverse_policy::wrap DEFAULT_WRAP_POLICY;
    00884 #else
    00885     typedef traverse_policy::no_wrap DEFAULT_WRAP_POLICY;
    00886 #endif
    00887
    00888 #ifndef BOOST_UBLAS_DEFAULT_ASSIGN_BY_COLUMN
    00889     typedef traverse_policy::by_row_policy<DEFAULT_WRAP_POLICY> DEFAULT_TRAVERSE_POLICY;
    00890 #else
    00891     typedef traverse_policy::by_column<DEFAULT_WRAP_POLICY> DEFAULT_TRAVERSE_POLICY;
    00892 #endif
    00893
    00894  // Traverse policy namespace
    00895 namespace traverse_policy {
    00896
    00897     by_row_policy<DEFAULT_WRAP_POLICY> by_row() {
    00898     return by_row_policy<DEFAULT_WRAP_POLICY>();
    00899     }
    00900
    00901     by_row_policy<wrap> by_row_wrap() {
    00902         return by_row_policy<wrap>();
    00903     }
    00904
    00905     by_row_policy<no_wrap> by_row_no_wrap() {
    00906         return by_row_policy<no_wrap>();
    00907     }
    00908
    00909     by_column_policy<DEFAULT_WRAP_POLICY> by_column() {
    00910         return by_column_policy<DEFAULT_WRAP_POLICY>();
    00911     }
    00912
    00913     by_column_policy<wrap> by_column_wrap() {
    00914         return by_column_policy<wrap>();
    00915     }
    00916
    00917     by_column_policy<no_wrap> by_column_no_wrap() {
    00918         return by_column_policy<no_wrap>();
    00919     }
    00920
    00921 }
    00922
    00931 template <class E, class Fill_Policy = fill_policy::index_assign>
    00932 class vector_expression_assigner {
    00933 public:
    00934     typedef typename E::expression_type::value_type value_type;
    00935     typedef typename E::expression_type::size_type size_type;
    00936
    00937     BOOST_UBLAS_INLINE
    00938     vector_expression_assigner(E &e):ve(e), i(0) {
    00939     }
    00940
    00941     BOOST_UBLAS_INLINE
    00942     vector_expression_assigner(size_type k, E &e):ve(e), i(k) {
    00943         // Overloaded like that so it can be differentiated from (E, val).
    00944         // Otherwise there would be an ambiquity when value_type == size_type.
    00945     }
    00946
    00947     BOOST_UBLAS_INLINE
    00948     vector_expression_assigner(E &e, value_type val):ve(e), i(0) {
    00949         operator,(val);
    00950     }
    00951
    00952     template <class AE>
    00953     BOOST_UBLAS_INLINE
    00954     vector_expression_assigner(E &e, const vector_expression<AE> &nve):ve(e), i(0) {
    00955         operator,(nve);
    00956     }
    00957
    00958     template <typename T>
    00959     BOOST_UBLAS_INLINE
    00960     vector_expression_assigner(E &e, const index_manipulator<T> &ta):ve(e), i(0) {
    00961         operator,(ta);
    00962     }
    00963
    00964     BOOST_UBLAS_INLINE
    00965     vector_expression_assigner &operator, (const value_type& val) {
    00966         apply(val);
    00967         return *this;
    00968     }
    00969
    00970     template <class AE>
    00971     BOOST_UBLAS_INLINE
    00972     vector_expression_assigner &operator, (const vector_expression<AE> &nve) {
    00973         for (typename AE::size_type k = 0; k!= nve().size(); k++)
    00974             operator,(nve()(k));
    00975         return *this;
    00976     }
    00977
    00978     template <typename T>
    00979     BOOST_UBLAS_INLINE
    00980     vector_expression_assigner &operator, (const index_manipulator<T> &ta) {
    00981         ta().manip(i);
    00982         return *this;
    00983     }
    00984
    00985     template <class T>
    00986     BOOST_UBLAS_INLINE
    00987     vector_expression_assigner<E, T> operator, (fill_policy_wrapper<T>) const {
    00988         return vector_expression_assigner<E, T>(i, ve);
    00989     }
    00990
    00991 private:
    00992     BOOST_UBLAS_INLINE
    00993     vector_expression_assigner &apply(const typename E::expression_type::value_type& val) {
    00994         Fill_Policy::apply(ve, i++, val);
    00995         return *this;
    00996     }
    00997
    00998 private:
    00999     E &ve;
    01000     size_type i;
    01001 };
    01002
    01003 /*
    01004 // The following static assigner is about 30% slower than the dynamic one, probably due to the recursive creation of assigner objects.
    01005 // It remains commented here for future reference.
    01006
    01007 template <class E, std::size_t I=0>
    01008 class static_vector_expression_assigner {
    01009 public:
    01010     typedef typename E::expression_type::value_type value_type;
    01011     typedef typename E::expression_type::size_type size_type;
    01012
    01013     BOOST_UBLAS_INLINE
    01014     static_vector_expression_assigner(E &e):ve(e) {
    01015     }
    01016
    01017     BOOST_UBLAS_INLINE
    01018     static_vector_expression_assigner(E &e, value_type val):ve(e) {
    01019         operator,(val);
    01020     }
    01021
    01022     BOOST_UBLAS_INLINE
    01023     static_vector_expression_assigner<E, I+1> operator, (const value_type& val) {
    01024         return apply(val);
    01025     }
    01026
    01027 private:
    01028     BOOST_UBLAS_INLINE
    01029     static_vector_expression_assigner<E, I+1> apply(const typename E::expression_type::value_type& val) {
    01030         ve()(I)=val;
    01031         return static_vector_expression_assigner<E, I+1>(ve);
    01032     }
    01033
    01034 private:
    01035     E &ve;
    01036 };
    01037
    01038 template <class E>
    01039 BOOST_UBLAS_INLINE
    01040 static_vector_expression_assigner<vector_expression<E>, 1 > test_static(vector_expression<E> &v, const typename E::value_type &val) {
    01041     v()(0)=val;
    01042     return static_vector_expression_assigner<vector_expression<E>, 1 >(v);
    01043 }
    01044 */
    01045
    01046
    01054 template <class E>
    01055 BOOST_UBLAS_INLINE
    01056 vector_expression_assigner<vector_expression<E> > operator<<=(vector_expression<E> &v, const typename E::value_type &val) {
    01057     return vector_expression_assigner<vector_expression<E> >(v,val);
    01058 }
    01059
    01067 template <class E1, class E2>
    01068 BOOST_UBLAS_INLINE
    01069 vector_expression_assigner<vector_expression<E1> > operator<<=(vector_expression<E1> &v, const vector_expression<E2> &ve) {
    01070     return vector_expression_assigner<vector_expression<E1> >(v,ve);
    01071 }
    01072
    01080 template <class E, typename T>
    01081 BOOST_UBLAS_INLINE
    01082 vector_expression_assigner<vector_expression<E> > operator<<=(vector_expression<E> &v, const index_manipulator<T> &nv) {
    01083     return vector_expression_assigner<vector_expression<E> >(v,nv);
    01084 }
    01085
    01093 template <class E, typename T>
    01094 BOOST_UBLAS_INLINE
    01095 vector_expression_assigner<vector_expression<E>, T> operator<<=(vector_expression<E> &v, fill_policy_wrapper<T>) {
    01096     return vector_expression_assigner<vector_expression<E>, T>(v);
    01097 }
    01098
    01107 template <class E, class Fill_Policy = fill_policy::index_assign, class Traverse_Policy = DEFAULT_TRAVERSE_POLICY >
    01108 class matrix_expression_assigner {
    01109 public:
    01110     typedef typename E::expression_type::size_type size_type;
    01111
    01112     BOOST_UBLAS_INLINE
    01113     matrix_expression_assigner(E &e): me(e), i(0), j(0) {
    01114     }
    01115
    01116     BOOST_UBLAS_INLINE
    01117     matrix_expression_assigner(E &e, size_type k, size_type l): me(e), i(k), j(l) {
    01118     }
    01119
    01120     BOOST_UBLAS_INLINE
    01121     matrix_expression_assigner(E &e, typename E::expression_type::value_type val): me(e), i(0), j(0) {
    01122         operator,(val);
    01123     }
    01124
    01125     template <class AE>
    01126     BOOST_UBLAS_INLINE
    01127     matrix_expression_assigner(E &e, const vector_expression<AE> &nve):me(e), i(0), j(0) {
    01128         operator,(nve);
    01129     }
    01130
    01131     template <class AE>
    01132     BOOST_UBLAS_INLINE
    01133     matrix_expression_assigner(E &e, const matrix_expression<AE> &nme):me(e), i(0), j(0) {
    01134         operator,(nme);
    01135     }
    01136
    01137     template <typename T>
    01138     BOOST_UBLAS_INLINE
    01139     matrix_expression_assigner(E &e, const index_manipulator<T> &ta):me(e), i(0), j(0) {
    01140         operator,(ta);
    01141     }
    01142
    01143     BOOST_UBLAS_INLINE
    01144     matrix_expression_assigner &operator, (const typename E::expression_type::value_type& val) {
    01145         Traverse_Policy::apply_wrap(me, i ,j);
    01146         return apply(val);
    01147     }
    01148
    01149     template <class AE>
    01150     BOOST_UBLAS_INLINE
    01151     matrix_expression_assigner &operator, (const vector_expression<AE> &nve) {
    01152         for (typename AE::size_type k = 0; k!= nve().size(); k++) {
    01153             operator,(nve()(k));
    01154         }
    01155         return *this;
    01156     }
    01157
    01158     template <class AE>
    01159     BOOST_UBLAS_INLINE
    01160     matrix_expression_assigner &operator, (const matrix_expression<AE> &nme) {
    01161         return apply(nme);
    01162     }
    01163
    01164     template <typename T>
    01165     BOOST_UBLAS_INLINE
    01166     matrix_expression_assigner &operator, (const index_manipulator<T> &ta) {
    01167         ta().manip(i, j);
    01168         return *this;
    01169     }
    01170
    01171     template <class T>
    01172     BOOST_UBLAS_INLINE
    01173     matrix_expression_assigner<E, T, Traverse_Policy> operator, (fill_policy_wrapper<T>) const {
    01174         return matrix_expression_assigner<E, T, Traverse_Policy>(me, i, j);
    01175     }
    01176
    01177
    01178     template <class T>
    01179     BOOST_UBLAS_INLINE
    01180     matrix_expression_assigner<E, Fill_Policy, T> operator, (traverse_policy_wrapper<T>) {
    01181         Traverse_Policy::apply_wrap(me, i ,j);
    01182         return matrix_expression_assigner<E, Fill_Policy, T>(me, i, j);
    01183     }
    01184
    01185 private:
    01186     BOOST_UBLAS_INLINE
    01187     matrix_expression_assigner &apply(const typename E::expression_type::value_type& val) {
    01188         Fill_Policy::apply(me, i, j, val);
    01189         Traverse_Policy::advance(i,j);
    01190         return *this;
    01191     }
    01192
    01193     template <class AE>
    01194     BOOST_UBLAS_INLINE
    01195     matrix_expression_assigner &apply(const matrix_expression<AE> &nme) {
    01196         size_type bi = i;
    01197         size_type bj = j;
    01198         typename AE::size_type k=0, l=0;
    01199         Fill_Policy::apply(me, i, j, nme()(k, l));
    01200         while (Traverse_Policy::next(nme, me, i, j, bi, bj, k, l))
    01201             Fill_Policy::apply(me, i, j, nme()(k, l));
    01202         return *this;
    01203     }
    01204
    01205 private:
    01206     E &me;
    01207     size_type i, j;
    01208 };
    01209
    01217 template <class E>
    01218 BOOST_UBLAS_INLINE
    01219 matrix_expression_assigner<matrix_expression<E> > operator<<=(matrix_expression<E> &me, const typename E::value_type &val) {
    01220     return matrix_expression_assigner<matrix_expression<E> >(me,val);
    01221 }
    01222
    01230 template <class E, typename T>
    01231 BOOST_UBLAS_INLINE
    01232 matrix_expression_assigner<matrix_expression<E>, T> operator<<=(matrix_expression<E> &me, fill_policy_wrapper<T>) {
    01233     return matrix_expression_assigner<matrix_expression<E>, T>(me);
    01234 }
    01235
    01243 template <class E, typename T>
    01244 BOOST_UBLAS_INLINE
    01245 matrix_expression_assigner<matrix_expression<E> > operator<<=(matrix_expression<E> &me, const index_manipulator<T> &ta) {
    01246     return matrix_expression_assigner<matrix_expression<E> >(me,ta);
    01247 }
    01248
    01256 template <class E, typename T>
    01257 BOOST_UBLAS_INLINE
    01258 matrix_expression_assigner<matrix_expression<E>, fill_policy::index_assign, T> operator<<=(matrix_expression<E> &me, traverse_policy_wrapper<T>) {
    01259     return matrix_expression_assigner<matrix_expression<E>, fill_policy::index_assign, T>(me);
    01260 }
    01261
    01269 template <class E1, class E2>
    01270 BOOST_UBLAS_INLINE
    01271 matrix_expression_assigner<matrix_expression<E1> > operator<<=(matrix_expression<E1> &me, const vector_expression<E2> &ve) {
    01272     return matrix_expression_assigner<matrix_expression<E1> >(me,ve);
    01273 }
    01274
    01282 template <class E1, class E2>
    01283 BOOST_UBLAS_INLINE
    01284 matrix_expression_assigner<matrix_expression<E1> > operator<<=(matrix_expression<E1> &me1, const matrix_expression<E2> &me2) {
    01285     return matrix_expression_assigner<matrix_expression<E1> >(me1,me2);
    01286 }
    01287
    01288 } } }
    01289
    01290 #endif // ASSIGNMENT_HPP