123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785 |
- //
- // Copyright (c) 2000-2002
- // Joerg Walter, Mathias Koch
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- // The authors gratefully acknowledge the support of
- // GeNeSys mbH & Co. KG in producing this work.
- //
- #ifndef _BOOST_UBLAS_MATRIX_ASSIGN_
- #define _BOOST_UBLAS_MATRIX_ASSIGN_
- #include <boost/numeric/ublas/traits.hpp>
- // Required for make_conformant storage
- #include <vector>
- // Iterators based on ideas of Jeremy Siek
- namespace boost { namespace numeric { namespace ublas {
- namespace detail {
-
- // Weak equality check - useful to compare equality two arbitary matrix expression results.
- // Since the actual expressions are unknown, we check for and arbitary error bound
- // on the relative error.
- // For a linear expression the infinity norm makes sense as we do not know how the elements will be
- // combined in the expression. False positive results are inevitable for arbirary expressions!
- template<class E1, class E2, class S>
- BOOST_UBLAS_INLINE
- bool equals (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2, S epsilon, S min_norm) {
- return norm_inf (e1 - e2) <= epsilon *
- std::max<S> (std::max<S> (norm_inf (e1), norm_inf (e2)), min_norm);
- }
- template<class E1, class E2>
- BOOST_UBLAS_INLINE
- bool expression_type_check (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
- typedef typename type_traits<typename promote_traits<typename E1::value_type,
- typename E2::value_type>::promote_type>::real_type real_type;
- return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
- }
- template<class M, class E, class R>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void make_conformant (M &m, const matrix_expression<E> &e, row_major_tag, R) {
- BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
- BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
- typedef R conformant_restrict_type;
- typedef typename M::size_type size_type;
- typedef typename M::difference_type difference_type;
- typedef typename M::value_type value_type;
- // FIXME unbounded_array with push_back maybe better
- std::vector<std::pair<size_type, size_type> > index;
- typename M::iterator1 it1 (m.begin1 ());
- typename M::iterator1 it1_end (m.end1 ());
- typename E::const_iterator1 it1e (e ().begin1 ());
- typename E::const_iterator1 it1e_end (e ().end1 ());
- while (it1 != it1_end && it1e != it1e_end) {
- difference_type compare = it1.index1 () - it1e.index1 ();
- if (compare == 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename M::iterator2 it2_end (it1.end ());
- typename E::const_iterator2 it2e (it1e.begin ());
- typename E::const_iterator2 it2e_end (it1e.end ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
- typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
- typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
- #endif
- if (it2 != it2_end && it2e != it2e_end) {
- size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
- for (;;) {
- difference_type compare2 = it2_index - it2e_index;
- if (compare2 == 0) {
- ++ it2, ++ it2e;
- if (it2 != it2_end && it2e != it2e_end) {
- it2_index = it2.index2 ();
- it2e_index = it2e.index2 ();
- } else
- break;
- } else if (compare2 < 0) {
- increment (it2, it2_end, - compare2);
- if (it2 != it2_end)
- it2_index = it2.index2 ();
- else
- break;
- } else if (compare2 > 0) {
- if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
- if (static_cast<value_type>(*it2e) != value_type/*zero*/())
- index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
- ++ it2e;
- if (it2e != it2e_end)
- it2e_index = it2e.index2 ();
- else
- break;
- }
- }
- }
- while (it2e != it2e_end) {
- if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
- if (static_cast<value_type>(*it2e) != value_type/*zero*/())
- index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
- ++ it2e;
- }
- ++ it1, ++ it1e;
- } else if (compare < 0) {
- increment (it1, it1_end, - compare);
- } else if (compare > 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename E::const_iterator2 it2e (it1e.begin ());
- typename E::const_iterator2 it2e_end (it1e.end ());
- #else
- typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
- typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
- #endif
- while (it2e != it2e_end) {
- if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
- if (static_cast<value_type>(*it2e) != value_type/*zero*/())
- index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
- ++ it2e;
- }
- ++ it1e;
- }
- }
- while (it1e != it1e_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename E::const_iterator2 it2e (it1e.begin ());
- typename E::const_iterator2 it2e_end (it1e.end ());
- #else
- typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
- typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
- #endif
- while (it2e != it2e_end) {
- if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
- if (static_cast<value_type>(*it2e) != value_type/*zero*/())
- index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
- ++ it2e;
- }
- ++ it1e;
- }
- // ISSUE proxies require insert_element
- for (size_type k = 0; k < index.size (); ++ k)
- m (index [k].first, index [k].second) = value_type/*zero*/();
- }
- template<class M, class E, class R>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void make_conformant (M &m, const matrix_expression<E> &e, column_major_tag, R) {
- BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
- BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
- typedef R conformant_restrict_type;
- typedef typename M::size_type size_type;
- typedef typename M::difference_type difference_type;
- typedef typename M::value_type value_type;
- std::vector<std::pair<size_type, size_type> > index;
- typename M::iterator2 it2 (m.begin2 ());
- typename M::iterator2 it2_end (m.end2 ());
- typename E::const_iterator2 it2e (e ().begin2 ());
- typename E::const_iterator2 it2e_end (e ().end2 ());
- while (it2 != it2_end && it2e != it2e_end) {
- difference_type compare = it2.index2 () - it2e.index2 ();
- if (compare == 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename M::iterator1 it1_end (it2.end ());
- typename E::const_iterator1 it1e (it2e.begin ());
- typename E::const_iterator1 it1e_end (it2e.end ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
- typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
- typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
- #endif
- if (it1 != it1_end && it1e != it1e_end) {
- size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
- for (;;) {
- difference_type compare2 = it1_index - it1e_index;
- if (compare2 == 0) {
- ++ it1, ++ it1e;
- if (it1 != it1_end && it1e != it1e_end) {
- it1_index = it1.index1 ();
- it1e_index = it1e.index1 ();
- } else
- break;
- } else if (compare2 < 0) {
- increment (it1, it1_end, - compare2);
- if (it1 != it1_end)
- it1_index = it1.index1 ();
- else
- break;
- } else if (compare2 > 0) {
- if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
- if (static_cast<value_type>(*it1e) != value_type/*zero*/())
- index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
- ++ it1e;
- if (it1e != it1e_end)
- it1e_index = it1e.index1 ();
- else
- break;
- }
- }
- }
- while (it1e != it1e_end) {
- if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
- if (static_cast<value_type>(*it1e) != value_type/*zero*/())
- index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
- ++ it1e;
- }
- ++ it2, ++ it2e;
- } else if (compare < 0) {
- increment (it2, it2_end, - compare);
- } else if (compare > 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename E::const_iterator1 it1e (it2e.begin ());
- typename E::const_iterator1 it1e_end (it2e.end ());
- #else
- typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
- typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
- #endif
- while (it1e != it1e_end) {
- if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
- if (static_cast<value_type>(*it1e) != value_type/*zero*/())
- index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
- ++ it1e;
- }
- ++ it2e;
- }
- }
- while (it2e != it2e_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename E::const_iterator1 it1e (it2e.begin ());
- typename E::const_iterator1 it1e_end (it2e.end ());
- #else
- typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
- typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
- #endif
- while (it1e != it1e_end) {
- if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
- if (static_cast<value_type>(*it1e) != value_type/*zero*/())
- index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
- ++ it1e;
- }
- ++ it2e;
- }
- // ISSUE proxies require insert_element
- for (size_type k = 0; k < index.size (); ++ k)
- m (index [k].first, index [k].second) = value_type/*zero*/();
- }
- }//namespace detail
- // Explicitly iterating row major
- template<template <class T1, class T2> class F, class M, class T>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void iterating_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
- typedef F<typename M::iterator2::reference, T> functor_type;
- typedef typename M::difference_type difference_type;
- difference_type size1 (m.size1 ());
- difference_type size2 (m.size2 ());
- typename M::iterator1 it1 (m.begin1 ());
- BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
- while (-- size1 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- #endif
- BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
- difference_type temp_size2 (size2);
- #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
- while (-- temp_size2 >= 0)
- functor_type::apply (*it2, t), ++ it2;
- #else
- DD (temp_size2, 4, r, (functor_type::apply (*it2, t), ++ it2));
- #endif
- ++ it1;
- }
- }
- // Explicitly iterating column major
- template<template <class T1, class T2> class F, class M, class T>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void iterating_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
- typedef F<typename M::iterator1::reference, T> functor_type;
- typedef typename M::difference_type difference_type;
- difference_type size2 (m.size2 ());
- difference_type size1 (m.size1 ());
- typename M::iterator2 it2 (m.begin2 ());
- BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
- while (-- size2 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- #endif
- BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
- difference_type temp_size1 (size1);
- #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
- while (-- temp_size1 >= 0)
- functor_type::apply (*it1, t), ++ it1;
- #else
- DD (temp_size1, 4, r, (functor_type::apply (*it1, t), ++ it1));
- #endif
- ++ it2;
- }
- }
- // Explicitly indexing row major
- template<template <class T1, class T2> class F, class M, class T>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void indexing_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
- typedef F<typename M::reference, T> functor_type;
- typedef typename M::size_type size_type;
- size_type size1 (m.size1 ());
- size_type size2 (m.size2 ());
- for (size_type i = 0; i < size1; ++ i) {
- #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
- for (size_type j = 0; j < size2; ++ j)
- functor_type::apply (m (i, j), t);
- #else
- size_type j (0);
- DD (size2, 4, r, (functor_type::apply (m (i, j), t), ++ j));
- #endif
- }
- }
- // Explicitly indexing column major
- template<template <class T1, class T2> class F, class M, class T>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void indexing_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
- typedef F<typename M::reference, T> functor_type;
- typedef typename M::size_type size_type;
- size_type size2 (m.size2 ());
- size_type size1 (m.size1 ());
- for (size_type j = 0; j < size2; ++ j) {
- #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
- for (size_type i = 0; i < size1; ++ i)
- functor_type::apply (m (i, j), t);
- #else
- size_type i (0);
- DD (size1, 4, r, (functor_type::apply (m (i, j), t), ++ i));
- #endif
- }
- }
- // Dense (proxy) case
- template<template <class T1, class T2> class F, class M, class T, class C>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign_scalar (M &m, const T &t, dense_proxy_tag, C) {
- typedef C orientation_category;
- #ifdef BOOST_UBLAS_USE_INDEXING
- indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
- #elif BOOST_UBLAS_USE_ITERATING
- iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
- #else
- typedef typename M::size_type size_type;
- size_type size1 (m.size1 ());
- size_type size2 (m.size2 ());
- if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
- size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
- iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
- else
- indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
- #endif
- }
- // Packed (proxy) row major case
- template<template <class T1, class T2> class F, class M, class T>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, row_major_tag) {
- typedef F<typename M::iterator2::reference, T> functor_type;
- typedef typename M::difference_type difference_type;
- typename M::iterator1 it1 (m.begin1 ());
- difference_type size1 (m.end1 () - it1);
- while (-- size1 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- difference_type size2 (it1.end () - it2);
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- difference_type size2 (end (it1, iterator1_tag ()) - it2);
- #endif
- while (-- size2 >= 0)
- functor_type::apply (*it2, t), ++ it2;
- ++ it1;
- }
- }
- // Packed (proxy) column major case
- template<template <class T1, class T2> class F, class M, class T>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, column_major_tag) {
- typedef F<typename M::iterator1::reference, T> functor_type;
- typedef typename M::difference_type difference_type;
- typename M::iterator2 it2 (m.begin2 ());
- difference_type size2 (m.end2 () - it2);
- while (-- size2 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- difference_type size1 (it2.end () - it1);
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- difference_type size1 (end (it2, iterator2_tag ()) - it1);
- #endif
- while (-- size1 >= 0)
- functor_type::apply (*it1, t), ++ it1;
- ++ it2;
- }
- }
- // Sparse (proxy) row major case
- template<template <class T1, class T2> class F, class M, class T>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, row_major_tag) {
- typedef F<typename M::iterator2::reference, T> functor_type;
- typename M::iterator1 it1 (m.begin1 ());
- typename M::iterator1 it1_end (m.end1 ());
- while (it1 != it1_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename M::iterator2 it2_end (it1.end ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
- #endif
- while (it2 != it2_end)
- functor_type::apply (*it2, t), ++ it2;
- ++ it1;
- }
- }
- // Sparse (proxy) column major case
- template<template <class T1, class T2> class F, class M, class T>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, column_major_tag) {
- typedef F<typename M::iterator1::reference, T> functor_type;
- typename M::iterator2 it2 (m.begin2 ());
- typename M::iterator2 it2_end (m.end2 ());
- while (it2 != it2_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename M::iterator1 it1_end (it2.end ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
- #endif
- while (it1 != it1_end)
- functor_type::apply (*it1, t), ++ it1;
- ++ it2;
- }
- }
- // Dispatcher
- template<template <class T1, class T2> class F, class M, class T>
- BOOST_UBLAS_INLINE
- void matrix_assign_scalar (M &m, const T &t) {
- typedef typename M::storage_category storage_category;
- typedef typename M::orientation_category orientation_category;
- matrix_assign_scalar<F> (m, t, storage_category (), orientation_category ());
- }
- template<class SC, bool COMPUTED, class RI1, class RI2>
- struct matrix_assign_traits {
- typedef SC storage_category;
- };
- template<bool COMPUTED>
- struct matrix_assign_traits<dense_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
- typedef packed_tag storage_category;
- };
- template<>
- struct matrix_assign_traits<dense_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
- typedef sparse_tag storage_category;
- };
- template<>
- struct matrix_assign_traits<dense_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
- typedef sparse_proxy_tag storage_category;
- };
- template<bool COMPUTED>
- struct matrix_assign_traits<dense_proxy_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
- typedef packed_proxy_tag storage_category;
- };
- template<bool COMPUTED>
- struct matrix_assign_traits<dense_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
- typedef sparse_proxy_tag storage_category;
- };
- template<>
- struct matrix_assign_traits<packed_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
- typedef sparse_tag storage_category;
- };
- template<>
- struct matrix_assign_traits<packed_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
- typedef sparse_proxy_tag storage_category;
- };
- template<bool COMPUTED>
- struct matrix_assign_traits<packed_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
- typedef sparse_proxy_tag storage_category;
- };
- template<>
- struct matrix_assign_traits<sparse_tag, true, dense_random_access_iterator_tag, dense_random_access_iterator_tag> {
- typedef sparse_proxy_tag storage_category;
- };
- template<>
- struct matrix_assign_traits<sparse_tag, true, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
- typedef sparse_proxy_tag storage_category;
- };
- template<>
- struct matrix_assign_traits<sparse_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
- typedef sparse_proxy_tag storage_category;
- };
- // Explicitly iterating row major
- template<template <class T1, class T2> class F, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void iterating_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
- typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
- typedef typename M::difference_type difference_type;
- difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
- difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
- typename M::iterator1 it1 (m.begin1 ());
- BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
- typename E::const_iterator1 it1e (e ().begin1 ());
- BOOST_UBLAS_CHECK (size2 == 0 || e ().end1 () - it1e == size1, bad_size ());
- while (-- size1 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename E::const_iterator2 it2e (it1e.begin ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
- #endif
- BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
- BOOST_UBLAS_CHECK (it1e.end () - it2e == size2, bad_size ());
- difference_type temp_size2 (size2);
- #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
- while (-- temp_size2 >= 0)
- functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
- #else
- DD (temp_size2, 2, r, (functor_type::apply (*it2, *it2e), ++ it2, ++ it2e));
- #endif
- ++ it1, ++ it1e;
- }
- }
- // Explicitly iterating column major
- template<template <class T1, class T2> class F, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void iterating_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
- typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
- typedef typename M::difference_type difference_type;
- difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
- difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
- typename M::iterator2 it2 (m.begin2 ());
- BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
- typename E::const_iterator2 it2e (e ().begin2 ());
- BOOST_UBLAS_CHECK (size1 == 0 || e ().end2 () - it2e == size2, bad_size ());
- while (-- size2 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename E::const_iterator1 it1e (it2e.begin ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
- #endif
- BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
- BOOST_UBLAS_CHECK (it2e.end () - it1e == size1, bad_size ());
- difference_type temp_size1 (size1);
- #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
- while (-- temp_size1 >= 0)
- functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
- #else
- DD (temp_size1, 2, r, (functor_type::apply (*it1, *it1e), ++ it1, ++ it1e));
- #endif
- ++ it2, ++ it2e;
- }
- }
- // Explicitly indexing row major
- template<template <class T1, class T2> class F, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void indexing_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
- typedef F<typename M::reference, typename E::value_type> functor_type;
- typedef typename M::size_type size_type;
- size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
- size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
- for (size_type i = 0; i < size1; ++ i) {
- #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
- for (size_type j = 0; j < size2; ++ j)
- functor_type::apply (m (i, j), e () (i, j));
- #else
- size_type j (0);
- DD (size2, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ j));
- #endif
- }
- }
- // Explicitly indexing column major
- template<template <class T1, class T2> class F, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void indexing_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
- typedef F<typename M::reference, typename E::value_type> functor_type;
- typedef typename M::size_type size_type;
- size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
- size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
- for (size_type j = 0; j < size2; ++ j) {
- #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
- for (size_type i = 0; i < size1; ++ i)
- functor_type::apply (m (i, j), e () (i, j));
- #else
- size_type i (0);
- DD (size1, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ i));
- #endif
- }
- }
- // Dense (proxy) case
- template<template <class T1, class T2> class F, class R, class M, class E, class C>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign (M &m, const matrix_expression<E> &e, dense_proxy_tag, C) {
- // R unnecessary, make_conformant not required
- typedef C orientation_category;
- #ifdef BOOST_UBLAS_USE_INDEXING
- indexing_matrix_assign<F> (m, e, orientation_category ());
- #elif BOOST_UBLAS_USE_ITERATING
- iterating_matrix_assign<F> (m, e, orientation_category ());
- #else
- typedef typename M::difference_type difference_type;
- size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
- size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
- if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
- size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
- iterating_matrix_assign<F> (m, e, orientation_category ());
- else
- indexing_matrix_assign<F> (m, e, orientation_category ());
- #endif
- }
- // Packed (proxy) row major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
- typedef typename matrix_traits<E>::value_type expr_value_type;
- typedef F<typename M::iterator2::reference, expr_value_type> functor_type;
- // R unnecessary, make_conformant not required
- typedef typename M::difference_type difference_type;
- BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
- BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
- #if BOOST_UBLAS_TYPE_CHECK
- typedef typename M::value_type value_type;
- matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
- indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
- indexing_matrix_assign<F> (cm, e, row_major_tag ());
- #endif
- typename M::iterator1 it1 (m.begin1 ());
- typename M::iterator1 it1_end (m.end1 ());
- typename E::const_iterator1 it1e (e ().begin1 ());
- typename E::const_iterator1 it1e_end (e ().end1 ());
- difference_type it1_size (it1_end - it1);
- difference_type it1e_size (it1e_end - it1e);
- difference_type diff1 (0);
- if (it1_size > 0 && it1e_size > 0)
- diff1 = it1.index1 () - it1e.index1 ();
- if (diff1 != 0) {
- difference_type size1 = (std::min) (diff1, it1e_size);
- if (size1 > 0) {
- it1e += size1;
- it1e_size -= size1;
- diff1 -= size1;
- }
- size1 = (std::min) (- diff1, it1_size);
- if (size1 > 0) {
- it1_size -= size1;
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (-- size1 >= 0) { // zeroing
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename M::iterator2 it2_end (it1.end ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
- #endif
- difference_type size2 (it2_end - it2);
- while (-- size2 >= 0)
- functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
- ++ it1;
- }
- } else {
- it1 += size1;
- }
- diff1 += size1;
- }
- }
- difference_type size1 ((std::min) (it1_size, it1e_size));
- it1_size -= size1;
- it1e_size -= size1;
- while (-- size1 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename M::iterator2 it2_end (it1.end ());
- typename E::const_iterator2 it2e (it1e.begin ());
- typename E::const_iterator2 it2e_end (it1e.end ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
- typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
- typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
- #endif
- difference_type it2_size (it2_end - it2);
- difference_type it2e_size (it2e_end - it2e);
- difference_type diff2 (0);
- if (it2_size > 0 && it2e_size > 0) {
- diff2 = it2.index2 () - it2e.index2 ();
- difference_type size2 = (std::min) (diff2, it2e_size);
- if (size2 > 0) {
- it2e += size2;
- it2e_size -= size2;
- diff2 -= size2;
- }
- size2 = (std::min) (- diff2, it2_size);
- if (size2 > 0) {
- it2_size -= size2;
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (-- size2 >= 0) // zeroing
- functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
- } else {
- it2 += size2;
- }
- diff2 += size2;
- }
- }
- difference_type size2 ((std::min) (it2_size, it2e_size));
- it2_size -= size2;
- it2e_size -= size2;
- while (-- size2 >= 0)
- functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
- size2 = it2_size;
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (-- size2 >= 0) // zeroing
- functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
- } else {
- it2 += size2;
- }
- ++ it1, ++ it1e;
- }
- size1 = it1_size;
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (-- size1 >= 0) { // zeroing
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename M::iterator2 it2_end (it1.end ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
- #endif
- difference_type size2 (it2_end - it2);
- while (-- size2 >= 0)
- functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
- ++ it1;
- }
- } else {
- it1 += size1;
- }
- #if BOOST_UBLAS_TYPE_CHECK
- if (! disable_type_check<bool>::value)
- BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
- #endif
- }
- // Packed (proxy) column major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
- typedef typename matrix_traits<E>::value_type expr_value_type;
- typedef F<typename M::iterator1::reference, expr_value_type> functor_type;
- // R unnecessary, make_conformant not required
- typedef typename M::difference_type difference_type;
- BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
- BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
- #if BOOST_UBLAS_TYPE_CHECK
- typedef typename M::value_type value_type;
- matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
- indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
- indexing_matrix_assign<F> (cm, e, column_major_tag ());
- #endif
- typename M::iterator2 it2 (m.begin2 ());
- typename M::iterator2 it2_end (m.end2 ());
- typename E::const_iterator2 it2e (e ().begin2 ());
- typename E::const_iterator2 it2e_end (e ().end2 ());
- difference_type it2_size (it2_end - it2);
- difference_type it2e_size (it2e_end - it2e);
- difference_type diff2 (0);
- if (it2_size > 0 && it2e_size > 0)
- diff2 = it2.index2 () - it2e.index2 ();
- if (diff2 != 0) {
- difference_type size2 = (std::min) (diff2, it2e_size);
- if (size2 > 0) {
- it2e += size2;
- it2e_size -= size2;
- diff2 -= size2;
- }
- size2 = (std::min) (- diff2, it2_size);
- if (size2 > 0) {
- it2_size -= size2;
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (-- size2 >= 0) { // zeroing
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename M::iterator1 it1_end (it2.end ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
- #endif
- difference_type size1 (it1_end - it1);
- while (-- size1 >= 0)
- functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
- ++ it2;
- }
- } else {
- it2 += size2;
- }
- diff2 += size2;
- }
- }
- difference_type size2 ((std::min) (it2_size, it2e_size));
- it2_size -= size2;
- it2e_size -= size2;
- while (-- size2 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename M::iterator1 it1_end (it2.end ());
- typename E::const_iterator1 it1e (it2e.begin ());
- typename E::const_iterator1 it1e_end (it2e.end ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
- typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
- typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
- #endif
- difference_type it1_size (it1_end - it1);
- difference_type it1e_size (it1e_end - it1e);
- difference_type diff1 (0);
- if (it1_size > 0 && it1e_size > 0) {
- diff1 = it1.index1 () - it1e.index1 ();
- difference_type size1 = (std::min) (diff1, it1e_size);
- if (size1 > 0) {
- it1e += size1;
- it1e_size -= size1;
- diff1 -= size1;
- }
- size1 = (std::min) (- diff1, it1_size);
- if (size1 > 0) {
- it1_size -= size1;
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (-- size1 >= 0) // zeroing
- functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
- } else {
- it1 += size1;
- }
- diff1 += size1;
- }
- }
- difference_type size1 ((std::min) (it1_size, it1e_size));
- it1_size -= size1;
- it1e_size -= size1;
- while (-- size1 >= 0)
- functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
- size1 = it1_size;
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (-- size1 >= 0) // zeroing
- functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
- } else {
- it1 += size1;
- }
- ++ it2, ++ it2e;
- }
- size2 = it2_size;
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (-- size2 >= 0) { // zeroing
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename M::iterator1 it1_end (it2.end ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
- #endif
- difference_type size1 (it1_end - it1);
- while (-- size1 >= 0)
- functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
- ++ it2;
- }
- } else {
- it2 += size2;
- }
- #if BOOST_UBLAS_TYPE_CHECK
- if (! disable_type_check<bool>::value)
- BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
- #endif
- }
- // Sparse row major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, row_major_tag) {
- typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
- // R unnecessary, make_conformant not required
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- BOOST_STATIC_ASSERT ((!functor_type::computed));
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
- BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
- typedef typename M::value_type value_type;
- // Sparse type has no numeric constraints to check
- m.clear ();
- typename E::const_iterator1 it1e (e ().begin1 ());
- typename E::const_iterator1 it1e_end (e ().end1 ());
- while (it1e != it1e_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename E::const_iterator2 it2e (it1e.begin ());
- typename E::const_iterator2 it2e_end (it1e.end ());
- #else
- typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
- typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
- #endif
- while (it2e != it2e_end) {
- value_type t (*it2e);
- if (t != value_type/*zero*/())
- m.insert_element (it2e.index1 (), it2e.index2 (), t);
- ++ it2e;
- }
- ++ it1e;
- }
- }
- // Sparse column major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, column_major_tag) {
- typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
- // R unnecessary, make_conformant not required
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- BOOST_STATIC_ASSERT ((!functor_type::computed));
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
- BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
- typedef typename M::value_type value_type;
- // Sparse type has no numeric constraints to check
- m.clear ();
- typename E::const_iterator2 it2e (e ().begin2 ());
- typename E::const_iterator2 it2e_end (e ().end2 ());
- while (it2e != it2e_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename E::const_iterator1 it1e (it2e.begin ());
- typename E::const_iterator1 it1e_end (it2e.end ());
- #else
- typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
- typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
- #endif
- while (it1e != it1e_end) {
- value_type t (*it1e);
- if (t != value_type/*zero*/())
- m.insert_element (it1e.index1 (), it1e.index2 (), t);
- ++ it1e;
- }
- ++ it2e;
- }
- }
- // Sparse proxy or functional row major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
- typedef typename matrix_traits<E>::value_type expr_value_type;
- typedef F<typename M::iterator2::reference, expr_value_type> functor_type;
- typedef R conformant_restrict_type;
- typedef typename M::size_type size_type;
- typedef typename M::difference_type difference_type;
- BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
- BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
- #if BOOST_UBLAS_TYPE_CHECK
- typedef typename M::value_type value_type;
- matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
- indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
- indexing_matrix_assign<F> (cm, e, row_major_tag ());
- #endif
- detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
- typename M::iterator1 it1 (m.begin1 ());
- typename M::iterator1 it1_end (m.end1 ());
- typename E::const_iterator1 it1e (e ().begin1 ());
- typename E::const_iterator1 it1e_end (e ().end1 ());
- while (it1 != it1_end && it1e != it1e_end) {
- difference_type compare = it1.index1 () - it1e.index1 ();
- if (compare == 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename M::iterator2 it2_end (it1.end ());
- typename E::const_iterator2 it2e (it1e.begin ());
- typename E::const_iterator2 it2e_end (it1e.end ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
- typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
- typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
- #endif
- if (it2 != it2_end && it2e != it2e_end) {
- size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
- for (;;) {
- difference_type compare2 = it2_index - it2e_index;
- if (compare2 == 0) {
- functor_type::apply (*it2, *it2e);
- ++ it2, ++ it2e;
- if (it2 != it2_end && it2e != it2e_end) {
- it2_index = it2.index2 ();
- it2e_index = it2e.index2 ();
- } else
- break;
- } else if (compare2 < 0) {
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- functor_type::apply (*it2, expr_value_type/*zero*/());
- ++ it2;
- } else
- increment (it2, it2_end, - compare2);
- if (it2 != it2_end)
- it2_index = it2.index2 ();
- else
- break;
- } else if (compare2 > 0) {
- increment (it2e, it2e_end, compare2);
- if (it2e != it2e_end)
- it2e_index = it2e.index2 ();
- else
- break;
- }
- }
- }
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (it2 != it2_end) { // zeroing
- functor_type::apply (*it2, expr_value_type/*zero*/());
- ++ it2;
- }
- } else {
- it2 = it2_end;
- }
- ++ it1, ++ it1e;
- } else if (compare < 0) {
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename M::iterator2 it2_end (it1.end ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
- #endif
- while (it2 != it2_end) { // zeroing
- functor_type::apply (*it2, expr_value_type/*zero*/());
- ++ it2;
- }
- ++ it1;
- } else {
- increment (it1, it1_end, - compare);
- }
- } else if (compare > 0) {
- increment (it1e, it1e_end, compare);
- }
- }
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (it1 != it1_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename M::iterator2 it2_end (it1.end ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
- #endif
- while (it2 != it2_end) { // zeroing
- functor_type::apply (*it2, expr_value_type/*zero*/());
- ++ it2;
- }
- ++ it1;
- }
- } else {
- it1 = it1_end;
- }
- #if BOOST_UBLAS_TYPE_CHECK
- if (! disable_type_check<bool>::value)
- BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
- #endif
- }
- // Sparse proxy or functional column major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
- typedef typename matrix_traits<E>::value_type expr_value_type;
- typedef F<typename M::iterator1::reference, expr_value_type> functor_type;
- typedef R conformant_restrict_type;
- typedef typename M::size_type size_type;
- typedef typename M::difference_type difference_type;
- BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
- BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
- #if BOOST_UBLAS_TYPE_CHECK
- typedef typename M::value_type value_type;
- matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
- indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
- indexing_matrix_assign<F> (cm, e, column_major_tag ());
- #endif
- detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
- typename M::iterator2 it2 (m.begin2 ());
- typename M::iterator2 it2_end (m.end2 ());
- typename E::const_iterator2 it2e (e ().begin2 ());
- typename E::const_iterator2 it2e_end (e ().end2 ());
- while (it2 != it2_end && it2e != it2e_end) {
- difference_type compare = it2.index2 () - it2e.index2 ();
- if (compare == 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename M::iterator1 it1_end (it2.end ());
- typename E::const_iterator1 it1e (it2e.begin ());
- typename E::const_iterator1 it1e_end (it2e.end ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
- typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
- typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
- #endif
- if (it1 != it1_end && it1e != it1e_end) {
- size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
- for (;;) {
- difference_type compare2 = it1_index - it1e_index;
- if (compare2 == 0) {
- functor_type::apply (*it1, *it1e);
- ++ it1, ++ it1e;
- if (it1 != it1_end && it1e != it1e_end) {
- it1_index = it1.index1 ();
- it1e_index = it1e.index1 ();
- } else
- break;
- } else if (compare2 < 0) {
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- functor_type::apply (*it1, expr_value_type/*zero*/()); // zeroing
- ++ it1;
- } else
- increment (it1, it1_end, - compare2);
- if (it1 != it1_end)
- it1_index = it1.index1 ();
- else
- break;
- } else if (compare2 > 0) {
- increment (it1e, it1e_end, compare2);
- if (it1e != it1e_end)
- it1e_index = it1e.index1 ();
- else
- break;
- }
- }
- }
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (it1 != it1_end) { // zeroing
- functor_type::apply (*it1, expr_value_type/*zero*/());
- ++ it1;
- }
- } else {
- it1 = it1_end;
- }
- ++ it2, ++ it2e;
- } else if (compare < 0) {
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename M::iterator1 it1_end (it2.end ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
- #endif
- while (it1 != it1_end) { // zeroing
- functor_type::apply (*it1, expr_value_type/*zero*/());
- ++ it1;
- }
- ++ it2;
- } else {
- increment (it2, it2_end, - compare);
- }
- } else if (compare > 0) {
- increment (it2e, it2e_end, compare);
- }
- }
- //Disabled warning C4127 because the conditional expression is constant
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (!functor_type::computed) {
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- while (it2 != it2_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename M::iterator1 it1_end (it2.end ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
- #endif
- while (it1 != it1_end) { // zeroing
- functor_type::apply (*it1, expr_value_type/*zero*/());
- ++ it1;
- }
- ++ it2;
- }
- } else {
- it2 = it2_end;
- }
- #if BOOST_UBLAS_TYPE_CHECK
- if (! disable_type_check<bool>::value)
- BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
- #endif
- }
- // Dispatcher
- template<template <class T1, class T2> class F, class M, class E>
- BOOST_UBLAS_INLINE
- void matrix_assign (M &m, const matrix_expression<E> &e) {
- typedef typename matrix_assign_traits<typename M::storage_category,
- F<typename M::reference, typename E::value_type>::computed,
- typename E::const_iterator1::iterator_category,
- typename E::const_iterator2::iterator_category>::storage_category storage_category;
- // give preference to matrix M's orientation if known
- typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
- typename E::orientation_category ,
- typename M::orientation_category >::type orientation_category;
- typedef basic_full<typename M::size_type> unrestricted;
- matrix_assign<F, unrestricted> (m, e, storage_category (), orientation_category ());
- }
- template<template <class T1, class T2> class F, class R, class M, class E>
- BOOST_UBLAS_INLINE
- void matrix_assign (M &m, const matrix_expression<E> &e) {
- typedef R conformant_restrict_type;
- typedef typename matrix_assign_traits<typename M::storage_category,
- F<typename M::reference, typename E::value_type>::computed,
- typename E::const_iterator1::iterator_category,
- typename E::const_iterator2::iterator_category>::storage_category storage_category;
- // give preference to matrix M's orientation if known
- typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
- typename E::orientation_category ,
- typename M::orientation_category >::type orientation_category;
- matrix_assign<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
- }
- template<class SC, class RI1, class RI2>
- struct matrix_swap_traits {
- typedef SC storage_category;
- };
- template<>
- struct matrix_swap_traits<dense_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
- typedef sparse_proxy_tag storage_category;
- };
- template<>
- struct matrix_swap_traits<packed_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
- typedef sparse_proxy_tag storage_category;
- };
- // Dense (proxy) row major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, row_major_tag) {
- typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
- // R unnecessary, make_conformant not required
- //typedef typename M::size_type size_type; // gcc is complaining that this is not used, although this is not right
- typedef typename M::difference_type difference_type;
- typename M::iterator1 it1 (m.begin1 ());
- typename E::iterator1 it1e (e ().begin1 ());
- difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (e ().end1 () - it1e)));
- while (-- size1 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename E::iterator2 it2e (it1e.begin ());
- difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (it1e.end () - it2e)));
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
- difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (end (it1e, iterator1_tag ()) - it2e)));
- #endif
- while (-- size2 >= 0)
- functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
- ++ it1, ++ it1e;
- }
- }
- // Dense (proxy) column major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, column_major_tag) {
- typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
- // R unnecessary, make_conformant not required
- // typedef typename M::size_type size_type; // gcc is complaining that this is not used, although this is not right
- typedef typename M::difference_type difference_type;
- typename M::iterator2 it2 (m.begin2 ());
- typename E::iterator2 it2e (e ().begin2 ());
- difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (e ().end2 () - it2e)));
- while (-- size2 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename E::iterator1 it1e (it2e.begin ());
- difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (it2e.end () - it1e)));
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
- difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (end (it2e, iterator2_tag ()) - it1e)));
- #endif
- while (-- size1 >= 0)
- functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
- ++ it2, ++ it2e;
- }
- }
- // Packed (proxy) row major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
- typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
- // R unnecessary, make_conformant not required
- typedef typename M::difference_type difference_type;
- typename M::iterator1 it1 (m.begin1 ());
- typename E::iterator1 it1e (e ().begin1 ());
- difference_type size1 (BOOST_UBLAS_SAME (m.end1 () - it1, e ().end1 () - it1e));
- while (-- size1 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename E::iterator2 it2e (it1e.begin ());
- difference_type size2 (BOOST_UBLAS_SAME (it1.end () - it2, it1e.end () - it2e));
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
- difference_type size2 (BOOST_UBLAS_SAME (end (it1, iterator1_tag ()) - it2, end (it1e, iterator1_tag ()) - it2e));
- #endif
- while (-- size2 >= 0)
- functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
- ++ it1, ++ it1e;
- }
- }
- // Packed (proxy) column major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
- typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
- // R unnecessary, make_conformant not required
- typedef typename M::difference_type difference_type;
- typename M::iterator2 it2 (m.begin2 ());
- typename E::iterator2 it2e (e ().begin2 ());
- difference_type size2 (BOOST_UBLAS_SAME (m.end2 () - it2, e ().end2 () - it2e));
- while (-- size2 >= 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename E::iterator1 it1e (it2e.begin ());
- difference_type size1 (BOOST_UBLAS_SAME (it2.end () - it1, it2e.end () - it1e));
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
- difference_type size1 (BOOST_UBLAS_SAME (end (it2, iterator2_tag ()) - it1, end (it2e, iterator2_tag ()) - it1e));
- #endif
- while (-- size1 >= 0)
- functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
- ++ it2, ++ it2e;
- }
- }
- // Sparse (proxy) row major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
- typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
- typedef R conformant_restrict_type;
- typedef typename M::size_type size_type;
- typedef typename M::difference_type difference_type;
- BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
- BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
- detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
- // FIXME should be a seperate restriction for E
- detail::make_conformant (e (), m, row_major_tag (), conformant_restrict_type ());
- typename M::iterator1 it1 (m.begin1 ());
- typename M::iterator1 it1_end (m.end1 ());
- typename E::iterator1 it1e (e ().begin1 ());
- typename E::iterator1 it1e_end (e ().end1 ());
- while (it1 != it1_end && it1e != it1e_end) {
- difference_type compare = it1.index1 () - it1e.index1 ();
- if (compare == 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename M::iterator2 it2_end (it1.end ());
- typename E::iterator2 it2e (it1e.begin ());
- typename E::iterator2 it2e_end (it1e.end ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
- typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
- typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
- #endif
- if (it2 != it2_end && it2e != it2e_end) {
- size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
- for (;;) {
- difference_type compare2 = it2_index - it2e_index;
- if (compare2 == 0) {
- functor_type::apply (*it2, *it2e);
- ++ it2, ++ it2e;
- if (it2 != it2_end && it2e != it2e_end) {
- it2_index = it2.index2 ();
- it2e_index = it2e.index2 ();
- } else
- break;
- } else if (compare2 < 0) {
- increment (it2, it2_end, - compare2);
- if (it2 != it2_end)
- it2_index = it2.index2 ();
- else
- break;
- } else if (compare2 > 0) {
- increment (it2e, it2e_end, compare2);
- if (it2e != it2e_end)
- it2e_index = it2e.index2 ();
- else
- break;
- }
- }
- }
- #if BOOST_UBLAS_TYPE_CHECK
- increment (it2e, it2e_end);
- increment (it2, it2_end);
- #endif
- ++ it1, ++ it1e;
- } else if (compare < 0) {
- #if BOOST_UBLAS_TYPE_CHECK
- while (it1.index1 () < it1e.index1 ()) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename M::iterator2 it2_end (it1.end ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
- #endif
- increment (it2, it2_end);
- ++ it1;
- }
- #else
- increment (it1, it1_end, - compare);
- #endif
- } else if (compare > 0) {
- #if BOOST_UBLAS_TYPE_CHECK
- while (it1e.index1 () < it1.index1 ()) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename E::iterator2 it2e (it1e.begin ());
- typename E::iterator2 it2e_end (it1e.end ());
- #else
- typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
- typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
- #endif
- increment (it2e, it2e_end);
- ++ it1e;
- }
- #else
- increment (it1e, it1e_end, compare);
- #endif
- }
- }
- #if BOOST_UBLAS_TYPE_CHECK
- while (it1e != it1e_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename E::iterator2 it2e (it1e.begin ());
- typename E::iterator2 it2e_end (it1e.end ());
- #else
- typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
- typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
- #endif
- increment (it2e, it2e_end);
- ++ it1e;
- }
- while (it1 != it1_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator2 it2 (it1.begin ());
- typename M::iterator2 it2_end (it1.end ());
- #else
- typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
- typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
- #endif
- increment (it2, it2_end);
- ++ it1;
- }
- #endif
- }
- // Sparse (proxy) column major case
- template<template <class T1, class T2> class F, class R, class M, class E>
- // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
- void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
- typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
- typedef R conformant_restrict_type;
- typedef typename M::size_type size_type;
- typedef typename M::difference_type difference_type;
- BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
- BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
- detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
- // FIXME should be a seperate restriction for E
- detail::make_conformant (e (), m, column_major_tag (), conformant_restrict_type ());
- typename M::iterator2 it2 (m.begin2 ());
- typename M::iterator2 it2_end (m.end2 ());
- typename E::iterator2 it2e (e ().begin2 ());
- typename E::iterator2 it2e_end (e ().end2 ());
- while (it2 != it2_end && it2e != it2e_end) {
- difference_type compare = it2.index2 () - it2e.index2 ();
- if (compare == 0) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename M::iterator1 it1_end (it2.end ());
- typename E::iterator1 it1e (it2e.begin ());
- typename E::iterator1 it1e_end (it2e.end ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
- typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
- typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
- #endif
- if (it1 != it1_end && it1e != it1e_end) {
- size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
- for (;;) {
- difference_type compare2 = it1_index - it1e_index;
- if (compare2 == 0) {
- functor_type::apply (*it1, *it1e);
- ++ it1, ++ it1e;
- if (it1 != it1_end && it1e != it1e_end) {
- it1_index = it1.index1 ();
- it1e_index = it1e.index1 ();
- } else
- break;
- } else if (compare2 < 0) {
- increment (it1, it1_end, - compare2);
- if (it1 != it1_end)
- it1_index = it1.index1 ();
- else
- break;
- } else if (compare2 > 0) {
- increment (it1e, it1e_end, compare2);
- if (it1e != it1e_end)
- it1e_index = it1e.index1 ();
- else
- break;
- }
- }
- }
- #if BOOST_UBLAS_TYPE_CHECK
- increment (it1e, it1e_end);
- increment (it1, it1_end);
- #endif
- ++ it2, ++ it2e;
- } else if (compare < 0) {
- #if BOOST_UBLAS_TYPE_CHECK
- while (it2.index2 () < it2e.index2 ()) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename M::iterator1 it1_end (it2.end ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
- #endif
- increment (it1, it1_end);
- ++ it2;
- }
- #else
- increment (it2, it2_end, - compare);
- #endif
- } else if (compare > 0) {
- #if BOOST_UBLAS_TYPE_CHECK
- while (it2e.index2 () < it2.index2 ()) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename E::iterator1 it1e (it2e.begin ());
- typename E::iterator1 it1e_end (it2e.end ());
- #else
- typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
- typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
- #endif
- increment (it1e, it1e_end);
- ++ it2e;
- }
- #else
- increment (it2e, it2e_end, compare);
- #endif
- }
- }
- #if BOOST_UBLAS_TYPE_CHECK
- while (it2e != it2e_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename E::iterator1 it1e (it2e.begin ());
- typename E::iterator1 it1e_end (it2e.end ());
- #else
- typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
- typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
- #endif
- increment (it1e, it1e_end);
- ++ it2e;
- }
- while (it2 != it2_end) {
- #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
- typename M::iterator1 it1 (it2.begin ());
- typename M::iterator1 it1_end (it2.end ());
- #else
- typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
- typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
- #endif
- increment (it1, it1_end);
- ++ it2;
- }
- #endif
- }
- // Dispatcher
- template<template <class T1, class T2> class F, class M, class E>
- BOOST_UBLAS_INLINE
- void matrix_swap (M &m, matrix_expression<E> &e) {
- typedef typename matrix_swap_traits<typename M::storage_category,
- typename E::const_iterator1::iterator_category,
- typename E::const_iterator2::iterator_category>::storage_category storage_category;
- // give preference to matrix M's orientation if known
- typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
- typename E::orientation_category ,
- typename M::orientation_category >::type orientation_category;
- typedef basic_full<typename M::size_type> unrestricted;
- matrix_swap<F, unrestricted> (m, e, storage_category (), orientation_category ());
- }
- template<template <class T1, class T2> class F, class R, class M, class E>
- BOOST_UBLAS_INLINE
- void matrix_swap (M &m, matrix_expression<E> &e) {
- typedef R conformant_restrict_type;
- typedef typename matrix_swap_traits<typename M::storage_category,
- typename E::const_iterator1::iterator_category,
- typename E::const_iterator2::iterator_category>::storage_category storage_category;
- // give preference to matrix M's orientation if known
- typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
- typename E::orientation_category ,
- typename M::orientation_category >::type orientation_category;
- matrix_swap<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
- }
- }}}
- #endif
|