00001
00002
00003
00004
00005
00006
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 &) 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 &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
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
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 &, S2 &, S3 &) {
00750 }
00751
00755 template <class S1, class S2, class S3>
00756 BOOST_UBLAS_INLINE
00757 static void apply2(const S1 &, const S1 &, S2 &, S3 &) {
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;
00786 else i1-=s1;
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 &, 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 &, const S3 &j0, S4 &k, S5 &l) {
00813 l++; j++;
00814 if (l>=e().size2()) {
00815 l=0; k++; j=j0; i++;
00816
00817
00818
00819
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 &) { 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 &, S4 &k, S5 &l) {
00859 k++; i++;
00860 if (k>=e().size1()) {
00861 k=0; l++; i=i0; j++;
00862
00863
00864
00865
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
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
00944
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
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
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