banded.hpp 85 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372
  1. //
  2. // Copyright (c) 2000-2013
  3. // Joerg Walter, Mathias Koch, Athanasios Iliopoulos
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // The authors gratefully acknowledge the support of
  10. // GeNeSys mbH & Co. KG in producing this work.
  11. //
  12. #ifndef _BOOST_UBLAS_BANDED_
  13. #define _BOOST_UBLAS_BANDED_
  14. #include <boost/numeric/ublas/matrix.hpp>
  15. #include <boost/numeric/ublas/detail/temporary.hpp>
  16. // Iterators based on ideas of Jeremy Siek
  17. namespace boost { namespace numeric { namespace ublas {
  18. namespace hidden {
  19. /** \brief A helper for band_matrix indexing.
  20. *
  21. * The indexing happens as per the netlib description: http://www.netlib.org/lapack/lug/node124.html.
  22. * In the case of a row_major matrix a different approach is followed;
  23. */
  24. template <class LayoutType>
  25. class banded_indexing { };
  26. /** \brief A helper for indexing column major banded matrices.
  27. *
  28. */
  29. template <>
  30. class banded_indexing<column_major_tag> {
  31. public:
  32. template <class T>
  33. BOOST_UBLAS_INLINE static T size(T /*size1*/, T size2) {
  34. return size2;
  35. }
  36. // template <class T>
  37. // BOOST_UBLAS_INLINE static bool valid_index(T size1, T /*size2*/, T lower, T upper, T i, T j) {
  38. // return (upper+i >= j) && i <= std::min(size1 - 1, j + lower); // upper + i is used by get_index. Maybe find a way to consolidate the operations to increase performance
  39. // }
  40. template <class T>
  41. BOOST_UBLAS_INLINE static T get_index(T /*size1*/, T size2, T lower, T upper, T i, T j) {
  42. return column_major::element (upper + i - j, lower + 1 + upper, j, size2);
  43. }
  44. };
  45. /** \brief A helper for indexing row major banded matrices.
  46. *
  47. */
  48. template <>
  49. class banded_indexing<row_major_tag> {
  50. public:
  51. template <class T>
  52. BOOST_UBLAS_INLINE static T size(T size1, T /*size2*/) {
  53. return size1;
  54. }
  55. // template <class T>
  56. // BOOST_UBLAS_INLINE static bool valid_index(T /*size1*/, T size2, T lower, T upper, T i, T j) {
  57. // return (lower+j >= i) && j <= std::min(size2 - 1, i + upper); // lower + j is used by get_index. Maybe find a way to consolidate the operations to increase performance
  58. // }
  59. template <class T>
  60. BOOST_UBLAS_INLINE static T get_index(T size1, T /*size2*/, T lower, T upper, T i, T j) {
  61. return row_major::element (i, size1, lower + j - i, lower + 1 + upper);
  62. }
  63. };
  64. }
  65. /** \brief A banded matrix of values of type \c T.
  66. *
  67. * For a \f$(mxn)\f$-dimensional banded matrix with \f$l\f$ lower and \f$u\f$ upper diagonals and
  68. * \f$0 \leq i < m\f$ and \f$0 \leq j < n\f$, if \f$i>j+l\f$ or \f$i<j-u\f$ then \f$b_{i,j}=0\f$.
  69. * The default storage for banded matrices is packed. Orientation and storage can also be specified.
  70. * Default is \c row_major and and unbounded_array. It is \b not required by the storage to initialize
  71. * elements of the matrix.
  72. *
  73. * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
  74. * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
  75. * \tparam A the type of Storage array. Default is \c unbounded_array
  76. */
  77. template<class T, class L, class A>
  78. class banded_matrix:
  79. public matrix_container<banded_matrix<T, L, A> > {
  80. typedef T *pointer;
  81. typedef L layout_type;
  82. typedef banded_matrix<T, L, A> self_type;
  83. public:
  84. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  85. using matrix_container<self_type>::operator ();
  86. #endif
  87. typedef typename A::size_type size_type;
  88. typedef typename A::difference_type difference_type;
  89. typedef T value_type;
  90. typedef const T &const_reference;
  91. typedef T &reference;
  92. typedef A array_type;
  93. typedef const matrix_reference<const self_type> const_closure_type;
  94. typedef matrix_reference<self_type> closure_type;
  95. typedef vector<T, A> vector_temporary_type;
  96. typedef matrix<T, L, A> matrix_temporary_type; // general sub-matrix
  97. typedef packed_tag storage_category;
  98. typedef typename L::orientation_category orientation_category;
  99. private:
  100. public:
  101. // Construction and destruction
  102. BOOST_UBLAS_INLINE
  103. banded_matrix ():
  104. matrix_container<self_type> (),
  105. size1_ (0), size2_ (0),
  106. lower_ (0), upper_ (0), data_ (0) {}
  107. BOOST_UBLAS_INLINE
  108. banded_matrix (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0):
  109. matrix_container<self_type> (),
  110. size1_ (size1), size2_ (size2),
  111. lower_ (lower), upper_ (upper),
  112. #if defined(BOOST_UBLAS_OWN_BANDED) || (BOOST_UBLAS_LEGACY_BANDED)
  113. data_ ((std::max) (size1, size2) * (lower + 1 + upper))
  114. #else
  115. data_ ( hidden::banded_indexing<orientation_category>::size(size1, size2) * (lower + 1 + upper)) // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
  116. #endif
  117. {
  118. }
  119. BOOST_UBLAS_INLINE
  120. banded_matrix (size_type size1, size_type size2, size_type lower, size_type upper, const array_type &data):
  121. matrix_container<self_type> (),
  122. size1_ (size1), size2_ (size2),
  123. lower_ (lower), upper_ (upper), data_ (data) {}
  124. BOOST_UBLAS_INLINE
  125. banded_matrix (const banded_matrix &m):
  126. matrix_container<self_type> (),
  127. size1_ (m.size1_), size2_ (m.size2_),
  128. lower_ (m.lower_), upper_ (m.upper_), data_ (m.data_) {}
  129. template<class AE>
  130. BOOST_UBLAS_INLINE
  131. banded_matrix (const matrix_expression<AE> &ae, size_type lower = 0, size_type upper = 0):
  132. matrix_container<self_type> (),
  133. size1_ (ae ().size1 ()), size2_ (ae ().size2 ()),
  134. lower_ (lower), upper_ (upper),
  135. #if defined(BOOST_UBLAS_OWN_BANDED) || (BOOST_UBLAS_LEGACY_BANDED)
  136. data_ ((std::max) (size1_, size2_) * (lower_ + 1 + upper_))
  137. #else
  138. data_ ( hidden::banded_indexing<orientation_category>::size(size1_, size2_) * (lower_ + 1 + upper_)) // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
  139. #endif
  140. {
  141. matrix_assign<scalar_assign> (*this, ae);
  142. }
  143. // Accessors
  144. BOOST_UBLAS_INLINE
  145. size_type size1 () const {
  146. return size1_;
  147. }
  148. BOOST_UBLAS_INLINE
  149. size_type size2 () const {
  150. return size2_;
  151. }
  152. BOOST_UBLAS_INLINE
  153. size_type lower () const {
  154. return lower_;
  155. }
  156. BOOST_UBLAS_INLINE
  157. size_type upper () const {
  158. return upper_;
  159. }
  160. // Storage accessors
  161. BOOST_UBLAS_INLINE
  162. const array_type &data () const {
  163. return data_;
  164. }
  165. BOOST_UBLAS_INLINE
  166. array_type &data () {
  167. return data_;
  168. }
  169. #if !defined (BOOST_UBLAS_OWN_BANDED)||(BOOST_UBLAS_LEGACY_BANDED)
  170. BOOST_UBLAS_INLINE
  171. bool is_element_in_band(size_type i, size_type j) const{
  172. //return (upper_+i >= j) && i <= std::min(size1() - 1, j + lower_); // We don't need to check if i is outside because it is checked anyway in the accessors.
  173. return (upper_+i >= j) && i <= ( j + lower_); // Essentially this band has "infinite" positive dimensions
  174. }
  175. #endif
  176. // Resizing
  177. BOOST_UBLAS_INLINE
  178. void resize (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0, bool preserve = true) {
  179. if (preserve) {
  180. self_type temporary (size1, size2, lower, upper);
  181. detail::matrix_resize_preserve<layout_type> (*this, temporary);
  182. }
  183. else {
  184. data ().resize ((std::max) (size1, size2) * (lower + 1 + upper));
  185. size1_ = size1;
  186. size2_ = size2;
  187. lower_ = lower;
  188. upper_ = upper;
  189. }
  190. }
  191. BOOST_UBLAS_INLINE
  192. void resize_packed_preserve (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0) {
  193. size1_ = size1;
  194. size2_ = size2;
  195. lower_ = lower;
  196. upper_ = upper;
  197. data ().resize ((std::max) (size1, size2) * (lower + 1 + upper), value_type ());
  198. }
  199. // Element access
  200. BOOST_UBLAS_INLINE
  201. const_reference operator () (size_type i, size_type j) const {
  202. BOOST_UBLAS_CHECK (i < size1_, bad_index ());
  203. BOOST_UBLAS_CHECK (j < size2_, bad_index ());
  204. #ifdef BOOST_UBLAS_OWN_BANDED
  205. const size_type k = (std::max) (i, j);
  206. const size_type l = lower_ + j - i;
  207. if (k < (std::max) (size1_, size2_) && // TODO: probably use BOOST_UBLAS_CHECK here instead of if
  208. l < lower_ + 1 + upper_)
  209. return data () [layout_type::element (k, (std::max) (size1_, size2_),
  210. l, lower_ + 1 + upper_)];
  211. #elif BOOST_UBLAS_LEGACY_BANDED // Prior to version: TODO: add version this is actually incorporated in
  212. const size_type k = j;
  213. const size_type l = upper_ + i - j;
  214. if (k < size2_ &&
  215. l < lower_ + 1 + upper_)
  216. return data () [layout_type::element (k, size2_,
  217. l, lower_ + 1 + upper_)];
  218. #else // New default
  219. // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
  220. if ( is_element_in_band( i, j) ) {
  221. return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
  222. }
  223. #endif
  224. return zero_;
  225. }
  226. BOOST_UBLAS_INLINE
  227. reference at_element (size_type i, size_type j) {
  228. BOOST_UBLAS_CHECK (i < size1_, bad_index ());
  229. BOOST_UBLAS_CHECK (j < size2_, bad_index ());
  230. #ifdef BOOST_UBLAS_OWN_BANDED
  231. const size_type k = (std::max) (i, j);
  232. const size_type l = lower_ + j - i; // TODO: Don't we need an if or BOOST_UBLAS_CHECK HERE?
  233. return data () [layout_type::element (k, (std::max) (size1_, size2_),
  234. l, lower_ + 1 + upper_)];
  235. #elif BOOST_UBLAS_LEGACY_BANDED // Prior to version: TODO: add version this is actually incorporated in
  236. const size_type k = j;
  237. const size_type l = upper_ + i - j;
  238. if (! (k < size2_ &&
  239. l < lower_ + 1 + upper_) ) {
  240. bad_index ().raise ();
  241. // NEVER reached
  242. }
  243. return data () [layout_type::element (k, size2_,
  244. l, lower_ + 1 + upper_)];
  245. #else
  246. // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
  247. BOOST_UBLAS_CHECK(is_element_in_band( i, j) , bad_index());
  248. return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
  249. #endif
  250. }
  251. BOOST_UBLAS_INLINE
  252. reference operator () (size_type i, size_type j) {
  253. BOOST_UBLAS_CHECK (i < size1_, bad_index ());
  254. BOOST_UBLAS_CHECK (j < size2_, bad_index ());
  255. #ifdef BOOST_UBLAS_OWN_BANDED
  256. const size_type k = (std::max) (i, j);
  257. const size_type l = lower_ + j - i;
  258. if (! (k < (std::max) (size1_, size2_) && // TODO: probably use BOOST_UBLAS_CHECK here instead of if
  259. l < lower_ + 1 + upper_) ) {
  260. bad_index ().raise ();
  261. // NEVER reached
  262. }
  263. return data () [layout_type::element (k, (std::max) (size1_, size2_),
  264. l, lower_ + 1 + upper_)];
  265. #elif BOOST_UBLAS_LEGACY_BANDED // Prior to version: TODO: add version this is actually incorporated in
  266. const size_type k = j;
  267. const size_type l = upper_ + i - j;
  268. if (! (k < size2_ &&
  269. l < lower_ + 1 + upper_) ) {
  270. bad_index ().raise ();
  271. // NEVER reached
  272. }
  273. return data () [layout_type::element (k, size2_,
  274. l, lower_ + 1 + upper_)];
  275. #else
  276. // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
  277. BOOST_UBLAS_CHECK( is_element_in_band( i, j) , bad_index());
  278. return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
  279. #endif
  280. }
  281. // Element assignment
  282. BOOST_UBLAS_INLINE
  283. reference insert_element (size_type i, size_type j, const_reference t) {
  284. return (operator () (i, j) = t);
  285. }
  286. BOOST_UBLAS_INLINE
  287. void erase_element (size_type i, size_type j) {
  288. operator () (i, j) = value_type/*zero*/();
  289. }
  290. // Zeroing
  291. BOOST_UBLAS_INLINE
  292. void clear () {
  293. std::fill (data ().begin (), data ().end (), value_type/*zero*/());
  294. }
  295. // Assignment
  296. BOOST_UBLAS_INLINE
  297. banded_matrix &operator = (const banded_matrix &m) {
  298. size1_ = m.size1_;
  299. size2_ = m.size2_;
  300. lower_ = m.lower_;
  301. upper_ = m.upper_;
  302. data () = m.data ();
  303. return *this;
  304. }
  305. BOOST_UBLAS_INLINE
  306. banded_matrix &assign_temporary (banded_matrix &m) {
  307. swap (m);
  308. return *this;
  309. }
  310. template<class AE>
  311. BOOST_UBLAS_INLINE
  312. banded_matrix &operator = (const matrix_expression<AE> &ae) {
  313. self_type temporary (ae, lower_, upper_);
  314. return assign_temporary (temporary);
  315. }
  316. template<class AE>
  317. BOOST_UBLAS_INLINE
  318. banded_matrix &assign (const matrix_expression<AE> &ae) {
  319. matrix_assign<scalar_assign> (*this, ae);
  320. return *this;
  321. }
  322. template<class AE>
  323. BOOST_UBLAS_INLINE
  324. banded_matrix& operator += (const matrix_expression<AE> &ae) {
  325. self_type temporary (*this + ae, lower_, upper_);
  326. return assign_temporary (temporary);
  327. }
  328. template<class AE>
  329. BOOST_UBLAS_INLINE
  330. banded_matrix &plus_assign (const matrix_expression<AE> &ae) {
  331. matrix_assign<scalar_plus_assign> (*this, ae);
  332. return *this;
  333. }
  334. template<class AE>
  335. BOOST_UBLAS_INLINE
  336. banded_matrix& operator -= (const matrix_expression<AE> &ae) {
  337. self_type temporary (*this - ae, lower_, upper_);
  338. return assign_temporary (temporary);
  339. }
  340. template<class AE>
  341. BOOST_UBLAS_INLINE
  342. banded_matrix &minus_assign (const matrix_expression<AE> &ae) {
  343. matrix_assign<scalar_minus_assign> (*this, ae);
  344. return *this;
  345. }
  346. template<class AT>
  347. BOOST_UBLAS_INLINE
  348. banded_matrix& operator *= (const AT &at) {
  349. matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
  350. return *this;
  351. }
  352. template<class AT>
  353. BOOST_UBLAS_INLINE
  354. banded_matrix& operator /= (const AT &at) {
  355. matrix_assign_scalar<scalar_divides_assign> (*this, at);
  356. return *this;
  357. }
  358. // Swapping
  359. BOOST_UBLAS_INLINE
  360. void swap (banded_matrix &m) {
  361. if (this != &m) {
  362. std::swap (size1_, m.size1_);
  363. std::swap (size2_, m.size2_);
  364. std::swap (lower_, m.lower_);
  365. std::swap (upper_, m.upper_);
  366. data ().swap (m.data ());
  367. }
  368. }
  369. BOOST_UBLAS_INLINE
  370. friend void swap (banded_matrix &m1, banded_matrix &m2) {
  371. m1.swap (m2);
  372. }
  373. // Iterator types
  374. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  375. typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
  376. typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
  377. typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
  378. typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
  379. #else
  380. class const_iterator1;
  381. class iterator1;
  382. class const_iterator2;
  383. class iterator2;
  384. #endif
  385. typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
  386. typedef reverse_iterator_base1<iterator1> reverse_iterator1;
  387. typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
  388. typedef reverse_iterator_base2<iterator2> reverse_iterator2;
  389. // Element lookup
  390. BOOST_UBLAS_INLINE
  391. const_iterator1 find1 (int rank, size_type i, size_type j) const {
  392. if (rank == 1) {
  393. size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
  394. i = (std::max) (i, lower_i);
  395. size_type upper_i = (std::min) (j + 1 + lower_, size1_);
  396. i = (std::min) (i, upper_i);
  397. }
  398. return const_iterator1 (*this, i, j);
  399. }
  400. BOOST_UBLAS_INLINE
  401. iterator1 find1 (int rank, size_type i, size_type j) {
  402. if (rank == 1) {
  403. size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
  404. i = (std::max) (i, lower_i);
  405. size_type upper_i = (std::min) (j + 1 + lower_, size1_);
  406. i = (std::min) (i, upper_i);
  407. }
  408. return iterator1 (*this, i, j);
  409. }
  410. BOOST_UBLAS_INLINE
  411. const_iterator2 find2 (int rank, size_type i, size_type j) const {
  412. if (rank == 1) {
  413. size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
  414. j = (std::max) (j, lower_j);
  415. size_type upper_j = (std::min) (i + 1 + upper_, size2_);
  416. j = (std::min) (j, upper_j);
  417. }
  418. return const_iterator2 (*this, i, j);
  419. }
  420. BOOST_UBLAS_INLINE
  421. iterator2 find2 (int rank, size_type i, size_type j) {
  422. if (rank == 1) {
  423. size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
  424. j = (std::max) (j, lower_j);
  425. size_type upper_j = (std::min) (i + 1 + upper_, size2_);
  426. j = (std::min) (j, upper_j);
  427. }
  428. return iterator2 (*this, i, j);
  429. }
  430. // Iterators simply are indices.
  431. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  432. class const_iterator1:
  433. public container_const_reference<banded_matrix>,
  434. public random_access_iterator_base<packed_random_access_iterator_tag,
  435. const_iterator1, value_type> {
  436. public:
  437. typedef typename banded_matrix::value_type value_type;
  438. typedef typename banded_matrix::difference_type difference_type;
  439. typedef typename banded_matrix::const_reference reference;
  440. typedef const typename banded_matrix::pointer pointer;
  441. typedef const_iterator2 dual_iterator_type;
  442. typedef const_reverse_iterator2 dual_reverse_iterator_type;
  443. // Construction and destruction
  444. BOOST_UBLAS_INLINE
  445. const_iterator1 ():
  446. container_const_reference<self_type> (), it1_ (), it2_ () {}
  447. BOOST_UBLAS_INLINE
  448. const_iterator1 (const self_type &m, size_type it1, size_type it2):
  449. container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
  450. BOOST_UBLAS_INLINE
  451. const_iterator1 (const iterator1 &it):
  452. container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
  453. // Arithmetic
  454. BOOST_UBLAS_INLINE
  455. const_iterator1 &operator ++ () {
  456. ++ it1_;
  457. return *this;
  458. }
  459. BOOST_UBLAS_INLINE
  460. const_iterator1 &operator -- () {
  461. -- it1_;
  462. return *this;
  463. }
  464. BOOST_UBLAS_INLINE
  465. const_iterator1 &operator += (difference_type n) {
  466. it1_ += n;
  467. return *this;
  468. }
  469. BOOST_UBLAS_INLINE
  470. const_iterator1 &operator -= (difference_type n) {
  471. it1_ -= n;
  472. return *this;
  473. }
  474. BOOST_UBLAS_INLINE
  475. difference_type operator - (const const_iterator1 &it) const {
  476. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  477. BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
  478. return it1_ - it.it1_;
  479. }
  480. // Dereference
  481. BOOST_UBLAS_INLINE
  482. const_reference operator * () const {
  483. return (*this) () (it1_, it2_);
  484. }
  485. BOOST_UBLAS_INLINE
  486. const_reference operator [] (difference_type n) const {
  487. return *(*this + n);
  488. }
  489. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  490. BOOST_UBLAS_INLINE
  491. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  492. typename self_type::
  493. #endif
  494. const_iterator2 begin () const {
  495. return (*this) ().find2 (1, it1_, 0);
  496. }
  497. BOOST_UBLAS_INLINE
  498. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  499. typename self_type::
  500. #endif
  501. const_iterator2 cbegin () const {
  502. return begin ();
  503. }
  504. BOOST_UBLAS_INLINE
  505. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  506. typename self_type::
  507. #endif
  508. const_iterator2 end () const {
  509. return (*this) ().find2 (1, it1_, (*this) ().size2 ());
  510. }
  511. BOOST_UBLAS_INLINE
  512. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  513. typename self_type::
  514. #endif
  515. const_iterator2 cend () const {
  516. return end ();
  517. }
  518. BOOST_UBLAS_INLINE
  519. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  520. typename self_type::
  521. #endif
  522. const_reverse_iterator2 rbegin () const {
  523. return const_reverse_iterator2 (end ());
  524. }
  525. BOOST_UBLAS_INLINE
  526. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  527. typename self_type::
  528. #endif
  529. const_reverse_iterator2 crbegin () const {
  530. return rbegin ();
  531. }
  532. BOOST_UBLAS_INLINE
  533. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  534. typename self_type::
  535. #endif
  536. const_reverse_iterator2 rend () const {
  537. return const_reverse_iterator2 (begin ());
  538. }
  539. BOOST_UBLAS_INLINE
  540. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  541. typename self_type::
  542. #endif
  543. const_reverse_iterator2 crend () const {
  544. return rend ();
  545. }
  546. #endif
  547. // Indices
  548. BOOST_UBLAS_INLINE
  549. size_type index1 () const {
  550. return it1_;
  551. }
  552. BOOST_UBLAS_INLINE
  553. size_type index2 () const {
  554. return it2_;
  555. }
  556. // Assignment
  557. BOOST_UBLAS_INLINE
  558. const_iterator1 &operator = (const const_iterator1 &it) {
  559. container_const_reference<self_type>::assign (&it ());
  560. it1_ = it.it1_;
  561. it2_ = it.it2_;
  562. return *this;
  563. }
  564. // Comparison
  565. BOOST_UBLAS_INLINE
  566. bool operator == (const const_iterator1 &it) const {
  567. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  568. BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
  569. return it1_ == it.it1_;
  570. }
  571. BOOST_UBLAS_INLINE
  572. bool operator < (const const_iterator1 &it) const {
  573. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  574. BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
  575. return it1_ < it.it1_;
  576. }
  577. private:
  578. size_type it1_;
  579. size_type it2_;
  580. };
  581. #endif
  582. BOOST_UBLAS_INLINE
  583. const_iterator1 begin1 () const {
  584. return find1 (0, 0, 0);
  585. }
  586. BOOST_UBLAS_INLINE
  587. const_iterator1 cbegin1 () const {
  588. return begin1 ();
  589. }
  590. BOOST_UBLAS_INLINE
  591. const_iterator1 end1 () const {
  592. return find1 (0, size1_, 0);
  593. }
  594. BOOST_UBLAS_INLINE
  595. const_iterator1 cend1 () const {
  596. return end1 ();
  597. }
  598. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  599. class iterator1:
  600. public container_reference<banded_matrix>,
  601. public random_access_iterator_base<packed_random_access_iterator_tag,
  602. iterator1, value_type> {
  603. public:
  604. typedef typename banded_matrix::value_type value_type;
  605. typedef typename banded_matrix::difference_type difference_type;
  606. typedef typename banded_matrix::reference reference;
  607. typedef typename banded_matrix::pointer pointer;
  608. typedef iterator2 dual_iterator_type;
  609. typedef reverse_iterator2 dual_reverse_iterator_type;
  610. // Construction and destruction
  611. BOOST_UBLAS_INLINE
  612. iterator1 ():
  613. container_reference<self_type> (), it1_ (), it2_ () {}
  614. BOOST_UBLAS_INLINE
  615. iterator1 (self_type &m, size_type it1, size_type it2):
  616. container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
  617. // Arithmetic
  618. BOOST_UBLAS_INLINE
  619. iterator1 &operator ++ () {
  620. ++ it1_;
  621. return *this;
  622. }
  623. BOOST_UBLAS_INLINE
  624. iterator1 &operator -- () {
  625. -- it1_;
  626. return *this;
  627. }
  628. BOOST_UBLAS_INLINE
  629. iterator1 &operator += (difference_type n) {
  630. it1_ += n;
  631. return *this;
  632. }
  633. BOOST_UBLAS_INLINE
  634. iterator1 &operator -= (difference_type n) {
  635. it1_ -= n;
  636. return *this;
  637. }
  638. BOOST_UBLAS_INLINE
  639. difference_type operator - (const iterator1 &it) const {
  640. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  641. BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
  642. return it1_ - it.it1_;
  643. }
  644. // Dereference
  645. BOOST_UBLAS_INLINE
  646. reference operator * () const {
  647. return (*this) ().at_element (it1_, it2_);
  648. }
  649. BOOST_UBLAS_INLINE
  650. reference operator [] (difference_type n) const {
  651. return *(*this + n);
  652. }
  653. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  654. BOOST_UBLAS_INLINE
  655. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  656. typename self_type::
  657. #endif
  658. iterator2 begin () const {
  659. return (*this) ().find2 (1, it1_, 0);
  660. }
  661. BOOST_UBLAS_INLINE
  662. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  663. typename self_type::
  664. #endif
  665. iterator2 end () const {
  666. return (*this) ().find2 (1, it1_, (*this) ().size2 ());
  667. }
  668. BOOST_UBLAS_INLINE
  669. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  670. typename self_type::
  671. #endif
  672. reverse_iterator2 rbegin () const {
  673. return reverse_iterator2 (end ());
  674. }
  675. BOOST_UBLAS_INLINE
  676. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  677. typename self_type::
  678. #endif
  679. reverse_iterator2 rend () const {
  680. return reverse_iterator2 (begin ());
  681. }
  682. #endif
  683. // Indices
  684. BOOST_UBLAS_INLINE
  685. size_type index1 () const {
  686. return it1_;
  687. }
  688. BOOST_UBLAS_INLINE
  689. size_type index2 () const {
  690. return it2_;
  691. }
  692. // Assignment
  693. BOOST_UBLAS_INLINE
  694. iterator1 &operator = (const iterator1 &it) {
  695. container_reference<self_type>::assign (&it ());
  696. it1_ = it.it1_;
  697. it2_ = it.it2_;
  698. return *this;
  699. }
  700. // Comparison
  701. BOOST_UBLAS_INLINE
  702. bool operator == (const iterator1 &it) const {
  703. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  704. BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
  705. return it1_ == it.it1_;
  706. }
  707. BOOST_UBLAS_INLINE
  708. bool operator < (const iterator1 &it) const {
  709. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  710. BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
  711. return it1_ < it.it1_;
  712. }
  713. private:
  714. size_type it1_;
  715. size_type it2_;
  716. friend class const_iterator1;
  717. };
  718. #endif
  719. BOOST_UBLAS_INLINE
  720. iterator1 begin1 () {
  721. return find1 (0, 0, 0);
  722. }
  723. BOOST_UBLAS_INLINE
  724. iterator1 end1 () {
  725. return find1 (0, size1_, 0);
  726. }
  727. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  728. class const_iterator2:
  729. public container_const_reference<banded_matrix>,
  730. public random_access_iterator_base<packed_random_access_iterator_tag,
  731. const_iterator2, value_type> {
  732. public:
  733. typedef typename banded_matrix::value_type value_type;
  734. typedef typename banded_matrix::difference_type difference_type;
  735. typedef typename banded_matrix::const_reference reference;
  736. typedef const typename banded_matrix::pointer pointer;
  737. typedef const_iterator1 dual_iterator_type;
  738. typedef const_reverse_iterator1 dual_reverse_iterator_type;
  739. // Construction and destruction
  740. BOOST_UBLAS_INLINE
  741. const_iterator2 ():
  742. container_const_reference<self_type> (), it1_ (), it2_ () {}
  743. BOOST_UBLAS_INLINE
  744. const_iterator2 (const self_type &m, size_type it1, size_type it2):
  745. container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
  746. BOOST_UBLAS_INLINE
  747. const_iterator2 (const iterator2 &it):
  748. container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
  749. // Arithmetic
  750. BOOST_UBLAS_INLINE
  751. const_iterator2 &operator ++ () {
  752. ++ it2_;
  753. return *this;
  754. }
  755. BOOST_UBLAS_INLINE
  756. const_iterator2 &operator -- () {
  757. -- it2_;
  758. return *this;
  759. }
  760. BOOST_UBLAS_INLINE
  761. const_iterator2 &operator += (difference_type n) {
  762. it2_ += n;
  763. return *this;
  764. }
  765. BOOST_UBLAS_INLINE
  766. const_iterator2 &operator -= (difference_type n) {
  767. it2_ -= n;
  768. return *this;
  769. }
  770. BOOST_UBLAS_INLINE
  771. difference_type operator - (const const_iterator2 &it) const {
  772. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  773. BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
  774. return it2_ - it.it2_;
  775. }
  776. // Dereference
  777. BOOST_UBLAS_INLINE
  778. const_reference operator * () const {
  779. return (*this) () (it1_, it2_);
  780. }
  781. BOOST_UBLAS_INLINE
  782. const_reference operator [] (difference_type n) const {
  783. return *(*this + n);
  784. }
  785. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  786. BOOST_UBLAS_INLINE
  787. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  788. typename self_type::
  789. #endif
  790. const_iterator1 begin () const {
  791. return (*this) ().find1 (1, 0, it2_);
  792. }
  793. BOOST_UBLAS_INLINE
  794. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  795. typename self_type::
  796. #endif
  797. const_iterator1 cbegin () const {
  798. return begin ();
  799. }
  800. BOOST_UBLAS_INLINE
  801. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  802. typename self_type::
  803. #endif
  804. const_iterator1 end () const {
  805. return (*this) ().find1 (1, (*this) ().size1 (), it2_);
  806. }
  807. BOOST_UBLAS_INLINE
  808. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  809. typename self_type::
  810. #endif
  811. const_iterator1 cend () const {
  812. return end();
  813. }
  814. BOOST_UBLAS_INLINE
  815. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  816. typename self_type::
  817. #endif
  818. const_reverse_iterator1 rbegin () const {
  819. return const_reverse_iterator1 (end ());
  820. }
  821. BOOST_UBLAS_INLINE
  822. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  823. typename self_type::
  824. #endif
  825. const_reverse_iterator1 crbegin () const {
  826. return rbegin ();
  827. }
  828. BOOST_UBLAS_INLINE
  829. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  830. typename self_type::
  831. #endif
  832. const_reverse_iterator1 rend () const {
  833. return const_reverse_iterator1 (begin ());
  834. }
  835. BOOST_UBLAS_INLINE
  836. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  837. typename self_type::
  838. #endif
  839. const_reverse_iterator1 crend () const {
  840. return rend ();
  841. }
  842. #endif
  843. // Indices
  844. BOOST_UBLAS_INLINE
  845. size_type index1 () const {
  846. return it1_;
  847. }
  848. BOOST_UBLAS_INLINE
  849. size_type index2 () const {
  850. return it2_;
  851. }
  852. // Assignment
  853. BOOST_UBLAS_INLINE
  854. const_iterator2 &operator = (const const_iterator2 &it) {
  855. container_const_reference<self_type>::assign (&it ());
  856. it1_ = it.it1_;
  857. it2_ = it.it2_;
  858. return *this;
  859. }
  860. // Comparison
  861. BOOST_UBLAS_INLINE
  862. bool operator == (const const_iterator2 &it) const {
  863. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  864. BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
  865. return it2_ == it.it2_;
  866. }
  867. BOOST_UBLAS_INLINE
  868. bool operator < (const const_iterator2 &it) const {
  869. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  870. BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
  871. return it2_ < it.it2_;
  872. }
  873. private:
  874. size_type it1_;
  875. size_type it2_;
  876. };
  877. #endif
  878. BOOST_UBLAS_INLINE
  879. const_iterator2 begin2 () const {
  880. return find2 (0, 0, 0);
  881. }
  882. BOOST_UBLAS_INLINE
  883. const_iterator2 cbegin2 () const {
  884. return begin2 ();
  885. }
  886. BOOST_UBLAS_INLINE
  887. const_iterator2 end2 () const {
  888. return find2 (0, 0, size2_);
  889. }
  890. BOOST_UBLAS_INLINE
  891. const_iterator2 cend2 () const {
  892. return end2 ();
  893. }
  894. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  895. class iterator2:
  896. public container_reference<banded_matrix>,
  897. public random_access_iterator_base<packed_random_access_iterator_tag,
  898. iterator2, value_type> {
  899. public:
  900. typedef typename banded_matrix::value_type value_type;
  901. typedef typename banded_matrix::difference_type difference_type;
  902. typedef typename banded_matrix::reference reference;
  903. typedef typename banded_matrix::pointer pointer;
  904. typedef iterator1 dual_iterator_type;
  905. typedef reverse_iterator1 dual_reverse_iterator_type;
  906. // Construction and destruction
  907. BOOST_UBLAS_INLINE
  908. iterator2 ():
  909. container_reference<self_type> (), it1_ (), it2_ () {}
  910. BOOST_UBLAS_INLINE
  911. iterator2 (self_type &m, size_type it1, size_type it2):
  912. container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
  913. // Arithmetic
  914. BOOST_UBLAS_INLINE
  915. iterator2 &operator ++ () {
  916. ++ it2_;
  917. return *this;
  918. }
  919. BOOST_UBLAS_INLINE
  920. iterator2 &operator -- () {
  921. -- it2_;
  922. return *this;
  923. }
  924. BOOST_UBLAS_INLINE
  925. iterator2 &operator += (difference_type n) {
  926. it2_ += n;
  927. return *this;
  928. }
  929. BOOST_UBLAS_INLINE
  930. iterator2 &operator -= (difference_type n) {
  931. it2_ -= n;
  932. return *this;
  933. }
  934. BOOST_UBLAS_INLINE
  935. difference_type operator - (const iterator2 &it) const {
  936. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  937. BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
  938. return it2_ - it.it2_;
  939. }
  940. // Dereference
  941. BOOST_UBLAS_INLINE
  942. reference operator * () const {
  943. return (*this) ().at_element (it1_, it2_);
  944. }
  945. BOOST_UBLAS_INLINE
  946. reference operator [] (difference_type n) const {
  947. return *(*this + n);
  948. }
  949. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  950. BOOST_UBLAS_INLINE
  951. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  952. typename self_type::
  953. #endif
  954. iterator1 begin () const {
  955. return (*this) ().find1 (1, 0, it2_);
  956. }
  957. BOOST_UBLAS_INLINE
  958. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  959. typename self_type::
  960. #endif
  961. iterator1 end () const {
  962. return (*this) ().find1 (1, (*this) ().size1 (), it2_);
  963. }
  964. BOOST_UBLAS_INLINE
  965. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  966. typename self_type::
  967. #endif
  968. reverse_iterator1 rbegin () const {
  969. return reverse_iterator1 (end ());
  970. }
  971. BOOST_UBLAS_INLINE
  972. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  973. typename self_type::
  974. #endif
  975. reverse_iterator1 rend () const {
  976. return reverse_iterator1 (begin ());
  977. }
  978. #endif
  979. // Indices
  980. BOOST_UBLAS_INLINE
  981. size_type index1 () const {
  982. return it1_;
  983. }
  984. BOOST_UBLAS_INLINE
  985. size_type index2 () const {
  986. return it2_;
  987. }
  988. // Assignment
  989. BOOST_UBLAS_INLINE
  990. iterator2 &operator = (const iterator2 &it) {
  991. container_reference<self_type>::assign (&it ());
  992. it1_ = it.it1_;
  993. it2_ = it.it2_;
  994. return *this;
  995. }
  996. // Comparison
  997. BOOST_UBLAS_INLINE
  998. bool operator == (const iterator2 &it) const {
  999. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1000. BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
  1001. return it2_ == it.it2_;
  1002. }
  1003. BOOST_UBLAS_INLINE
  1004. bool operator < (const iterator2 &it) const {
  1005. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1006. BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
  1007. return it2_ < it.it2_;
  1008. }
  1009. private:
  1010. size_type it1_;
  1011. size_type it2_;
  1012. friend class const_iterator2;
  1013. };
  1014. #endif
  1015. BOOST_UBLAS_INLINE
  1016. iterator2 begin2 () {
  1017. return find2 (0, 0, 0);
  1018. }
  1019. BOOST_UBLAS_INLINE
  1020. iterator2 end2 () {
  1021. return find2 (0, 0, size2_);
  1022. }
  1023. // Reverse iterators
  1024. BOOST_UBLAS_INLINE
  1025. const_reverse_iterator1 rbegin1 () const {
  1026. return const_reverse_iterator1 (end1 ());
  1027. }
  1028. BOOST_UBLAS_INLINE
  1029. const_reverse_iterator1 crbegin1 () const {
  1030. return rbegin1 ();
  1031. }
  1032. BOOST_UBLAS_INLINE
  1033. const_reverse_iterator1 rend1 () const {
  1034. return const_reverse_iterator1 (begin1 ());
  1035. }
  1036. BOOST_UBLAS_INLINE
  1037. const_reverse_iterator1 crend1 () const {
  1038. return rend1 ();
  1039. }
  1040. BOOST_UBLAS_INLINE
  1041. reverse_iterator1 rbegin1 () {
  1042. return reverse_iterator1 (end1 ());
  1043. }
  1044. BOOST_UBLAS_INLINE
  1045. reverse_iterator1 rend1 () {
  1046. return reverse_iterator1 (begin1 ());
  1047. }
  1048. BOOST_UBLAS_INLINE
  1049. const_reverse_iterator2 rbegin2 () const {
  1050. return const_reverse_iterator2 (end2 ());
  1051. }
  1052. BOOST_UBLAS_INLINE
  1053. const_reverse_iterator2 crbegin2 () const {
  1054. return rbegin2 ();
  1055. }
  1056. BOOST_UBLAS_INLINE
  1057. const_reverse_iterator2 rend2 () const {
  1058. return const_reverse_iterator2 (begin2 ());
  1059. }
  1060. BOOST_UBLAS_INLINE
  1061. const_reverse_iterator2 crend2 () const {
  1062. return rend2 ();
  1063. }
  1064. BOOST_UBLAS_INLINE
  1065. reverse_iterator2 rbegin2 () {
  1066. return reverse_iterator2 (end2 ());
  1067. }
  1068. BOOST_UBLAS_INLINE
  1069. reverse_iterator2 rend2 () {
  1070. return reverse_iterator2 (begin2 ());
  1071. }
  1072. private:
  1073. size_type size1_;
  1074. size_type size2_;
  1075. size_type lower_;
  1076. size_type upper_;
  1077. array_type data_;
  1078. typedef const value_type const_value_type;
  1079. static const_value_type zero_;
  1080. };
  1081. template<class T, class L, class A>
  1082. typename banded_matrix<T, L, A>::const_value_type banded_matrix<T, L, A>::zero_ = value_type/*zero*/();
  1083. /** \brief A diagonal matrix of values of type \c T, which is a specialization of a banded matrix
  1084. *
  1085. * For a \f$(m\times m)\f$-dimensional diagonal matrix, \f$0 \leq i < m\f$ and \f$0 \leq j < m\f$,
  1086. * if \f$i\neq j\f$ then \f$b_{i,j}=0\f$. The default storage for diagonal matrices is packed.
  1087. * Orientation and storage can also be specified. Default is \c row major \c unbounded_array.
  1088. *
  1089. * As a specialization of a banded matrix, the constructor of the diagonal matrix creates
  1090. * a banded matrix with 0 upper and lower diagonals around the main diagonal and the matrix is
  1091. * obviously a square matrix. Operations are optimized based on these 2 assumptions. It is
  1092. * \b not required by the storage to initialize elements of the matrix.
  1093. *
  1094. * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
  1095. * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
  1096. * \tparam A the type of Storage array. Default is \c unbounded_array
  1097. */
  1098. template<class T, class L, class A>
  1099. class diagonal_matrix:
  1100. public banded_matrix<T, L, A> {
  1101. public:
  1102. typedef typename A::size_type size_type;
  1103. typedef banded_matrix<T, L, A> matrix_type;
  1104. typedef A array_type;
  1105. // Construction and destruction
  1106. BOOST_UBLAS_INLINE
  1107. diagonal_matrix ():
  1108. matrix_type () {}
  1109. BOOST_UBLAS_INLINE
  1110. diagonal_matrix (size_type size):
  1111. matrix_type (size, size) {}
  1112. BOOST_UBLAS_INLINE
  1113. diagonal_matrix (size_type size, const array_type& data):
  1114. matrix_type (size, size, 0, 0, data) {}
  1115. BOOST_UBLAS_INLINE
  1116. diagonal_matrix (size_type size1, size_type size2):
  1117. matrix_type (size1, size2) {}
  1118. template<class AE>
  1119. BOOST_UBLAS_INLINE
  1120. diagonal_matrix (const matrix_expression<AE> &ae):
  1121. matrix_type (ae) {}
  1122. BOOST_UBLAS_INLINE
  1123. ~diagonal_matrix () {}
  1124. // Assignment
  1125. BOOST_UBLAS_INLINE
  1126. diagonal_matrix &operator = (const diagonal_matrix &m) {
  1127. matrix_type::operator = (m);
  1128. return *this;
  1129. }
  1130. template<class AE>
  1131. BOOST_UBLAS_INLINE
  1132. diagonal_matrix &operator = (const matrix_expression<AE> &ae) {
  1133. matrix_type::operator = (ae);
  1134. return *this;
  1135. }
  1136. };
  1137. /** \brief A banded matrix adaptator: convert a any matrix into a banded matrix expression
  1138. *
  1139. * For a \f$(m\times n)\f$-dimensional matrix, the \c banded_adaptor will provide a banded matrix
  1140. * with \f$l\f$ lower and \f$u\f$ upper diagonals and \f$0 \leq i < m\f$ and \f$0 \leq j < n\f$,
  1141. * if \f$i>j+l\f$ or \f$i<j-u\f$ then \f$b_{i,j}=0\f$.
  1142. *
  1143. * Storage and location are based on those of the underlying matrix. This is important because
  1144. * a \c banded_adaptor does not copy the matrix data to a new place. Therefore, modifying values
  1145. * in a \c banded_adaptor matrix will also modify the underlying matrix too.
  1146. *
  1147. * \tparam M the type of matrix used to generate a banded matrix
  1148. */
  1149. template<class M>
  1150. class banded_adaptor:
  1151. public matrix_expression<banded_adaptor<M> > {
  1152. typedef banded_adaptor<M> self_type;
  1153. public:
  1154. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  1155. using matrix_expression<self_type>::operator ();
  1156. #endif
  1157. typedef const M const_matrix_type;
  1158. typedef M matrix_type;
  1159. typedef typename M::size_type size_type;
  1160. typedef typename M::difference_type difference_type;
  1161. typedef typename M::value_type value_type;
  1162. typedef typename M::const_reference const_reference;
  1163. typedef typename boost::mpl::if_<boost::is_const<M>,
  1164. typename M::const_reference,
  1165. typename M::reference>::type reference;
  1166. typedef typename boost::mpl::if_<boost::is_const<M>,
  1167. typename M::const_closure_type,
  1168. typename M::closure_type>::type matrix_closure_type;
  1169. typedef const self_type const_closure_type;
  1170. typedef self_type closure_type;
  1171. // Replaced by _temporary_traits to avoid type requirements on M
  1172. //typedef typename M::vector_temporary_type vector_temporary_type;
  1173. //typedef typename M::matrix_temporary_type matrix_temporary_type;
  1174. typedef typename storage_restrict_traits<typename M::storage_category,
  1175. packed_proxy_tag>::storage_category storage_category;
  1176. typedef typename M::orientation_category orientation_category;
  1177. // Construction and destruction
  1178. BOOST_UBLAS_INLINE
  1179. banded_adaptor (matrix_type &data, size_type lower = 0, size_type upper = 0):
  1180. matrix_expression<self_type> (),
  1181. data_ (data), lower_ (lower), upper_ (upper) {}
  1182. BOOST_UBLAS_INLINE
  1183. banded_adaptor (const banded_adaptor &m):
  1184. matrix_expression<self_type> (),
  1185. data_ (m.data_), lower_ (m.lower_), upper_ (m.upper_) {}
  1186. // Accessors
  1187. BOOST_UBLAS_INLINE
  1188. size_type size1 () const {
  1189. return data_.size1 ();
  1190. }
  1191. BOOST_UBLAS_INLINE
  1192. size_type size2 () const {
  1193. return data_.size2 ();
  1194. }
  1195. BOOST_UBLAS_INLINE
  1196. size_type lower () const {
  1197. return lower_;
  1198. }
  1199. BOOST_UBLAS_INLINE
  1200. size_type upper () const {
  1201. return upper_;
  1202. }
  1203. // Storage accessors
  1204. BOOST_UBLAS_INLINE
  1205. const matrix_closure_type &data () const {
  1206. return data_;
  1207. }
  1208. BOOST_UBLAS_INLINE
  1209. matrix_closure_type &data () {
  1210. return data_;
  1211. }
  1212. #if !defined (BOOST_UBLAS_OWN_BANDED)||(BOOST_UBLAS_LEGACY_BANDED)
  1213. BOOST_UBLAS_INLINE
  1214. bool is_element_in_band(size_type i, size_type j) const{
  1215. //return (upper_+i >= j) && i <= std::min(size1() - 1, j + lower_); // We don't need to check if i is outside because it is checked anyway in the accessors.
  1216. return (upper_+i >= j) && i <= ( j + lower_); // Essentially this band has "infinite" positive dimensions
  1217. }
  1218. #endif
  1219. // Element access
  1220. #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
  1221. BOOST_UBLAS_INLINE
  1222. const_reference operator () (size_type i, size_type j) const {
  1223. BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
  1224. BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
  1225. #ifdef BOOST_UBLAS_OWN_BANDED
  1226. size_type k = (std::max) (i, j);
  1227. size_type l = lower_ + j - i;
  1228. if (k < (std::max) (size1 (), size2 ()) &&
  1229. l < lower_ + 1 + upper_)
  1230. return data () (i, j);
  1231. #elif BOOST_UBLAS_LEGACY_BANDED
  1232. size_type k = j;
  1233. size_type l = upper_ + i - j;
  1234. if (k < size2 () &&
  1235. l < lower_ + 1 + upper_)
  1236. return data () (i, j);
  1237. #else
  1238. if (is_element_in_band( i, j))
  1239. return data () (i, j);
  1240. #endif
  1241. return zero_;
  1242. }
  1243. BOOST_UBLAS_INLINE
  1244. reference operator () (size_type i, size_type j) {
  1245. BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
  1246. BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
  1247. #ifdef BOOST_UBLAS_OWN_BANDED
  1248. size_type k = (std::max) (i, j);
  1249. size_type l = lower_ + j - i;
  1250. if (k < (std::max) (size1 (), size2 ()) &&
  1251. l < lower_ + 1 + upper_)
  1252. return data () (i, j);
  1253. #elif BOOST_UBLAS_LEGACY_BANDED
  1254. size_type k = j;
  1255. size_type l = upper_ + i - j;
  1256. if (k < size2 () &&
  1257. l < lower_ + 1 + upper_)
  1258. return data () (i, j);
  1259. #else
  1260. if (is_element_in_band( i, j))
  1261. return data () (i, j);
  1262. #endif
  1263. #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
  1264. bad_index ().raise ();
  1265. #endif
  1266. return const_cast<reference>(zero_);
  1267. }
  1268. #else
  1269. BOOST_UBLAS_INLINE
  1270. reference operator () (size_type i, size_type j) const {
  1271. BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
  1272. BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
  1273. #ifdef BOOST_UBLAS_OWN_BANDED
  1274. size_type k = (std::max) (i, j);
  1275. size_type l = lower_ + j - i;
  1276. if (k < (std::max) (size1 (), size2 ()) &&
  1277. l < lower_ + 1 + upper_)
  1278. return data () (i, j);
  1279. #elif BOOST_UBLAS_LEGACY_BANDED
  1280. size_type k = j;
  1281. size_type l = upper_ + i - j;
  1282. if (k < size2 () &&
  1283. l < lower_ + 1 + upper_)
  1284. return data () (i, j);
  1285. #else
  1286. if (is_element_in_band( i, j))
  1287. return data () (i, j);
  1288. #endif
  1289. #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
  1290. bad_index ().raise ();
  1291. #endif
  1292. return const_cast<reference>(zero_);
  1293. }
  1294. #endif
  1295. // Assignment
  1296. BOOST_UBLAS_INLINE
  1297. banded_adaptor &operator = (const banded_adaptor &m) {
  1298. matrix_assign<scalar_assign> (*this, m);
  1299. return *this;
  1300. }
  1301. BOOST_UBLAS_INLINE
  1302. banded_adaptor &assign_temporary (banded_adaptor &m) {
  1303. *this = m;
  1304. return *this;
  1305. }
  1306. template<class AE>
  1307. BOOST_UBLAS_INLINE
  1308. banded_adaptor &operator = (const matrix_expression<AE> &ae) {
  1309. matrix_assign<scalar_assign> (*this, matrix<value_type> (ae));
  1310. return *this;
  1311. }
  1312. template<class AE>
  1313. BOOST_UBLAS_INLINE
  1314. banded_adaptor &assign (const matrix_expression<AE> &ae) {
  1315. matrix_assign<scalar_assign> (*this, ae);
  1316. return *this;
  1317. }
  1318. template<class AE>
  1319. BOOST_UBLAS_INLINE
  1320. banded_adaptor& operator += (const matrix_expression<AE> &ae) {
  1321. matrix_assign<scalar_assign> (*this, matrix<value_type> (*this + ae));
  1322. return *this;
  1323. }
  1324. template<class AE>
  1325. BOOST_UBLAS_INLINE
  1326. banded_adaptor &plus_assign (const matrix_expression<AE> &ae) {
  1327. matrix_assign<scalar_plus_assign> (*this, ae);
  1328. return *this;
  1329. }
  1330. template<class AE>
  1331. BOOST_UBLAS_INLINE
  1332. banded_adaptor& operator -= (const matrix_expression<AE> &ae) {
  1333. matrix_assign<scalar_assign> (*this, matrix<value_type> (*this - ae));
  1334. return *this;
  1335. }
  1336. template<class AE>
  1337. BOOST_UBLAS_INLINE
  1338. banded_adaptor &minus_assign (const matrix_expression<AE> &ae) {
  1339. matrix_assign<scalar_minus_assign> (*this, ae);
  1340. return *this;
  1341. }
  1342. template<class AT>
  1343. BOOST_UBLAS_INLINE
  1344. banded_adaptor& operator *= (const AT &at) {
  1345. matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
  1346. return *this;
  1347. }
  1348. template<class AT>
  1349. BOOST_UBLAS_INLINE
  1350. banded_adaptor& operator /= (const AT &at) {
  1351. matrix_assign_scalar<scalar_divides_assign> (*this, at);
  1352. return *this;
  1353. }
  1354. // Closure comparison
  1355. BOOST_UBLAS_INLINE
  1356. bool same_closure (const banded_adaptor &ba) const {
  1357. return (*this).data ().same_closure (ba.data ());
  1358. }
  1359. // Swapping
  1360. BOOST_UBLAS_INLINE
  1361. void swap (banded_adaptor &m) {
  1362. if (this != &m) {
  1363. BOOST_UBLAS_CHECK (lower_ == m.lower_, bad_size ());
  1364. BOOST_UBLAS_CHECK (upper_ == m.upper_, bad_size ());
  1365. matrix_swap<scalar_swap> (*this, m);
  1366. }
  1367. }
  1368. BOOST_UBLAS_INLINE
  1369. friend void swap (banded_adaptor &m1, banded_adaptor &m2) {
  1370. m1.swap (m2);
  1371. }
  1372. // Iterator types
  1373. private:
  1374. // Use the matrix iterator
  1375. typedef typename M::const_iterator1 const_subiterator1_type;
  1376. typedef typename boost::mpl::if_<boost::is_const<M>,
  1377. typename M::const_iterator1,
  1378. typename M::iterator1>::type subiterator1_type;
  1379. typedef typename M::const_iterator2 const_subiterator2_type;
  1380. typedef typename boost::mpl::if_<boost::is_const<M>,
  1381. typename M::const_iterator2,
  1382. typename M::iterator2>::type subiterator2_type;
  1383. public:
  1384. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1385. typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
  1386. typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
  1387. typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
  1388. typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
  1389. #else
  1390. class const_iterator1;
  1391. class iterator1;
  1392. class const_iterator2;
  1393. class iterator2;
  1394. #endif
  1395. typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
  1396. typedef reverse_iterator_base1<iterator1> reverse_iterator1;
  1397. typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
  1398. typedef reverse_iterator_base2<iterator2> reverse_iterator2;
  1399. // Element lookup
  1400. BOOST_UBLAS_INLINE
  1401. const_iterator1 find1 (int rank, size_type i, size_type j) const {
  1402. if (rank == 1) {
  1403. size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
  1404. i = (std::max) (i, lower_i);
  1405. size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
  1406. i = (std::min) (i, upper_i);
  1407. }
  1408. return const_iterator1 (*this, data ().find1 (rank, i, j));
  1409. }
  1410. BOOST_UBLAS_INLINE
  1411. iterator1 find1 (int rank, size_type i, size_type j) {
  1412. if (rank == 1) {
  1413. size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
  1414. i = (std::max) (i, lower_i);
  1415. size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
  1416. i = (std::min) (i, upper_i);
  1417. }
  1418. return iterator1 (*this, data ().find1 (rank, i, j));
  1419. }
  1420. BOOST_UBLAS_INLINE
  1421. const_iterator2 find2 (int rank, size_type i, size_type j) const {
  1422. if (rank == 1) {
  1423. size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
  1424. j = (std::max) (j, lower_j);
  1425. size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
  1426. j = (std::min) (j, upper_j);
  1427. }
  1428. return const_iterator2 (*this, data ().find2 (rank, i, j));
  1429. }
  1430. BOOST_UBLAS_INLINE
  1431. iterator2 find2 (int rank, size_type i, size_type j) {
  1432. if (rank == 1) {
  1433. size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
  1434. j = (std::max) (j, lower_j);
  1435. size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
  1436. j = (std::min) (j, upper_j);
  1437. }
  1438. return iterator2 (*this, data ().find2 (rank, i, j));
  1439. }
  1440. // Iterators simply are indices.
  1441. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1442. class const_iterator1:
  1443. public container_const_reference<banded_adaptor>,
  1444. public random_access_iterator_base<typename iterator_restrict_traits<
  1445. typename const_subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
  1446. const_iterator1, value_type> {
  1447. public:
  1448. typedef typename const_subiterator1_type::value_type value_type;
  1449. typedef typename const_subiterator1_type::difference_type difference_type;
  1450. typedef typename const_subiterator1_type::reference reference;
  1451. typedef typename const_subiterator1_type::pointer pointer;
  1452. typedef const_iterator2 dual_iterator_type;
  1453. typedef const_reverse_iterator2 dual_reverse_iterator_type;
  1454. // Construction and destruction
  1455. BOOST_UBLAS_INLINE
  1456. const_iterator1 ():
  1457. container_const_reference<self_type> (), it1_ () {}
  1458. BOOST_UBLAS_INLINE
  1459. const_iterator1 (const self_type &m, const const_subiterator1_type &it1):
  1460. container_const_reference<self_type> (m), it1_ (it1) {}
  1461. BOOST_UBLAS_INLINE
  1462. const_iterator1 (const iterator1 &it):
  1463. container_const_reference<self_type> (it ()), it1_ (it.it1_) {}
  1464. // Arithmetic
  1465. BOOST_UBLAS_INLINE
  1466. const_iterator1 &operator ++ () {
  1467. ++ it1_;
  1468. return *this;
  1469. }
  1470. BOOST_UBLAS_INLINE
  1471. const_iterator1 &operator -- () {
  1472. -- it1_;
  1473. return *this;
  1474. }
  1475. BOOST_UBLAS_INLINE
  1476. const_iterator1 &operator += (difference_type n) {
  1477. it1_ += n;
  1478. return *this;
  1479. }
  1480. BOOST_UBLAS_INLINE
  1481. const_iterator1 &operator -= (difference_type n) {
  1482. it1_ -= n;
  1483. return *this;
  1484. }
  1485. BOOST_UBLAS_INLINE
  1486. difference_type operator - (const const_iterator1 &it) const {
  1487. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1488. return it1_ - it.it1_;
  1489. }
  1490. // Dereference
  1491. BOOST_UBLAS_INLINE
  1492. const_reference operator * () const {
  1493. size_type i = index1 ();
  1494. size_type j = index2 ();
  1495. BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
  1496. BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
  1497. #ifdef BOOST_UBLAS_OWN_BANDED
  1498. size_type k = (std::max) (i, j);
  1499. size_type l = (*this) ().lower () + j - i;
  1500. if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
  1501. l < (*this) ().lower () + 1 + (*this) ().upper ())
  1502. return *it1_;
  1503. #else
  1504. size_type k = j;
  1505. size_type l = (*this) ().upper () + i - j;
  1506. if (k < (*this) ().size2 () &&
  1507. l < (*this) ().lower () + 1 + (*this) ().upper ())
  1508. return *it1_;
  1509. #endif
  1510. return (*this) () (i, j);
  1511. }
  1512. BOOST_UBLAS_INLINE
  1513. const_reference operator [] (difference_type n) const {
  1514. return *(*this + n);
  1515. }
  1516. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  1517. BOOST_UBLAS_INLINE
  1518. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1519. typename self_type::
  1520. #endif
  1521. const_iterator2 begin () const {
  1522. return (*this) ().find2 (1, index1 (), 0);
  1523. }
  1524. BOOST_UBLAS_INLINE
  1525. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1526. typename self_type::
  1527. #endif
  1528. const_iterator2 cbegin () const {
  1529. return begin ();
  1530. }
  1531. BOOST_UBLAS_INLINE
  1532. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1533. typename self_type::
  1534. #endif
  1535. const_iterator2 end () const {
  1536. return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
  1537. }
  1538. BOOST_UBLAS_INLINE
  1539. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1540. typename self_type::
  1541. #endif
  1542. const_iterator2 cend () const {
  1543. return end ();
  1544. }
  1545. BOOST_UBLAS_INLINE
  1546. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1547. typename self_type::
  1548. #endif
  1549. const_reverse_iterator2 rbegin () const {
  1550. return const_reverse_iterator2 (end ());
  1551. }
  1552. BOOST_UBLAS_INLINE
  1553. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1554. typename self_type::
  1555. #endif
  1556. const_reverse_iterator2 crbegin () const {
  1557. return rbegin ();
  1558. }
  1559. BOOST_UBLAS_INLINE
  1560. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1561. typename self_type::
  1562. #endif
  1563. const_reverse_iterator2 rend () const {
  1564. return const_reverse_iterator2 (begin ());
  1565. }
  1566. BOOST_UBLAS_INLINE
  1567. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1568. typename self_type::
  1569. #endif
  1570. const_reverse_iterator2 crend () const {
  1571. return rend ();
  1572. }
  1573. #endif
  1574. // Indices
  1575. BOOST_UBLAS_INLINE
  1576. size_type index1 () const {
  1577. return it1_.index1 ();
  1578. }
  1579. BOOST_UBLAS_INLINE
  1580. size_type index2 () const {
  1581. return it1_.index2 ();
  1582. }
  1583. // Assignment
  1584. BOOST_UBLAS_INLINE
  1585. const_iterator1 &operator = (const const_iterator1 &it) {
  1586. container_const_reference<self_type>::assign (&it ());
  1587. it1_ = it.it1_;
  1588. return *this;
  1589. }
  1590. // Comparison
  1591. BOOST_UBLAS_INLINE
  1592. bool operator == (const const_iterator1 &it) const {
  1593. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1594. return it1_ == it.it1_;
  1595. }
  1596. BOOST_UBLAS_INLINE
  1597. bool operator < (const const_iterator1 &it) const {
  1598. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1599. return it1_ < it.it1_;
  1600. }
  1601. private:
  1602. const_subiterator1_type it1_;
  1603. };
  1604. #endif
  1605. BOOST_UBLAS_INLINE
  1606. const_iterator1 begin1 () const {
  1607. return find1 (0, 0, 0);
  1608. }
  1609. BOOST_UBLAS_INLINE
  1610. const_iterator1 cbegin1 () const {
  1611. return begin1 ();
  1612. }
  1613. BOOST_UBLAS_INLINE
  1614. const_iterator1 end1 () const {
  1615. return find1 (0, size1 (), 0);
  1616. }
  1617. BOOST_UBLAS_INLINE
  1618. const_iterator1 cend1 () const {
  1619. return end1 ();
  1620. }
  1621. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1622. class iterator1:
  1623. public container_reference<banded_adaptor>,
  1624. public random_access_iterator_base<typename iterator_restrict_traits<
  1625. typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
  1626. iterator1, value_type> {
  1627. public:
  1628. typedef typename subiterator1_type::value_type value_type;
  1629. typedef typename subiterator1_type::difference_type difference_type;
  1630. typedef typename subiterator1_type::reference reference;
  1631. typedef typename subiterator1_type::pointer pointer;
  1632. typedef iterator2 dual_iterator_type;
  1633. typedef reverse_iterator2 dual_reverse_iterator_type;
  1634. // Construction and destruction
  1635. BOOST_UBLAS_INLINE
  1636. iterator1 ():
  1637. container_reference<self_type> (), it1_ () {}
  1638. BOOST_UBLAS_INLINE
  1639. iterator1 (self_type &m, const subiterator1_type &it1):
  1640. container_reference<self_type> (m), it1_ (it1) {}
  1641. // Arithmetic
  1642. BOOST_UBLAS_INLINE
  1643. iterator1 &operator ++ () {
  1644. ++ it1_;
  1645. return *this;
  1646. }
  1647. BOOST_UBLAS_INLINE
  1648. iterator1 &operator -- () {
  1649. -- it1_;
  1650. return *this;
  1651. }
  1652. BOOST_UBLAS_INLINE
  1653. iterator1 &operator += (difference_type n) {
  1654. it1_ += n;
  1655. return *this;
  1656. }
  1657. BOOST_UBLAS_INLINE
  1658. iterator1 &operator -= (difference_type n) {
  1659. it1_ -= n;
  1660. return *this;
  1661. }
  1662. BOOST_UBLAS_INLINE
  1663. difference_type operator - (const iterator1 &it) const {
  1664. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1665. return it1_ - it.it1_;
  1666. }
  1667. // Dereference
  1668. BOOST_UBLAS_INLINE
  1669. reference operator * () const {
  1670. size_type i = index1 ();
  1671. size_type j = index2 ();
  1672. BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
  1673. BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
  1674. #ifdef BOOST_UBLAS_OWN_BANDED
  1675. size_type k = (std::max) (i, j);
  1676. size_type l = (*this) ().lower () + j - i;
  1677. if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
  1678. l < (*this) ().lower () + 1 + (*this) ().upper ())
  1679. return *it1_;
  1680. #else
  1681. size_type k = j;
  1682. size_type l = (*this) ().upper () + i - j;
  1683. if (k < (*this) ().size2 () &&
  1684. l < (*this) ().lower () + 1 + (*this) ().upper ())
  1685. return *it1_;
  1686. #endif
  1687. return (*this) () (i, j);
  1688. }
  1689. BOOST_UBLAS_INLINE
  1690. reference operator [] (difference_type n) const {
  1691. return *(*this + n);
  1692. }
  1693. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  1694. BOOST_UBLAS_INLINE
  1695. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1696. typename self_type::
  1697. #endif
  1698. iterator2 begin () const {
  1699. return (*this) ().find2 (1, index1 (), 0);
  1700. }
  1701. BOOST_UBLAS_INLINE
  1702. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1703. typename self_type::
  1704. #endif
  1705. iterator2 end () const {
  1706. return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
  1707. }
  1708. BOOST_UBLAS_INLINE
  1709. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1710. typename self_type::
  1711. #endif
  1712. reverse_iterator2 rbegin () const {
  1713. return reverse_iterator2 (end ());
  1714. }
  1715. BOOST_UBLAS_INLINE
  1716. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1717. typename self_type::
  1718. #endif
  1719. reverse_iterator2 rend () const {
  1720. return reverse_iterator2 (begin ());
  1721. }
  1722. #endif
  1723. // Indices
  1724. BOOST_UBLAS_INLINE
  1725. size_type index1 () const {
  1726. return it1_.index1 ();
  1727. }
  1728. BOOST_UBLAS_INLINE
  1729. size_type index2 () const {
  1730. return it1_.index2 ();
  1731. }
  1732. // Assignment
  1733. BOOST_UBLAS_INLINE
  1734. iterator1 &operator = (const iterator1 &it) {
  1735. container_reference<self_type>::assign (&it ());
  1736. it1_ = it.it1_;
  1737. return *this;
  1738. }
  1739. // Comparison
  1740. BOOST_UBLAS_INLINE
  1741. bool operator == (const iterator1 &it) const {
  1742. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1743. return it1_ == it.it1_;
  1744. }
  1745. BOOST_UBLAS_INLINE
  1746. bool operator < (const iterator1 &it) const {
  1747. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1748. return it1_ < it.it1_;
  1749. }
  1750. private:
  1751. subiterator1_type it1_;
  1752. friend class const_iterator1;
  1753. };
  1754. #endif
  1755. BOOST_UBLAS_INLINE
  1756. iterator1 begin1 () {
  1757. return find1 (0, 0, 0);
  1758. }
  1759. BOOST_UBLAS_INLINE
  1760. iterator1 end1 () {
  1761. return find1 (0, size1 (), 0);
  1762. }
  1763. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1764. class const_iterator2:
  1765. public container_const_reference<banded_adaptor>,
  1766. public random_access_iterator_base<packed_random_access_iterator_tag,
  1767. const_iterator2, value_type> {
  1768. public:
  1769. typedef typename iterator_restrict_traits<typename const_subiterator2_type::iterator_category,
  1770. packed_random_access_iterator_tag>::iterator_category iterator_category;
  1771. typedef typename const_subiterator2_type::value_type value_type;
  1772. typedef typename const_subiterator2_type::difference_type difference_type;
  1773. typedef typename const_subiterator2_type::reference reference;
  1774. typedef typename const_subiterator2_type::pointer pointer;
  1775. typedef const_iterator1 dual_iterator_type;
  1776. typedef const_reverse_iterator1 dual_reverse_iterator_type;
  1777. // Construction and destruction
  1778. BOOST_UBLAS_INLINE
  1779. const_iterator2 ():
  1780. container_const_reference<self_type> (), it2_ () {}
  1781. BOOST_UBLAS_INLINE
  1782. const_iterator2 (const self_type &m, const const_subiterator2_type &it2):
  1783. container_const_reference<self_type> (m), it2_ (it2) {}
  1784. BOOST_UBLAS_INLINE
  1785. const_iterator2 (const iterator2 &it):
  1786. container_const_reference<self_type> (it ()), it2_ (it.it2_) {}
  1787. // Arithmetic
  1788. BOOST_UBLAS_INLINE
  1789. const_iterator2 &operator ++ () {
  1790. ++ it2_;
  1791. return *this;
  1792. }
  1793. BOOST_UBLAS_INLINE
  1794. const_iterator2 &operator -- () {
  1795. -- it2_;
  1796. return *this;
  1797. }
  1798. BOOST_UBLAS_INLINE
  1799. const_iterator2 &operator += (difference_type n) {
  1800. it2_ += n;
  1801. return *this;
  1802. }
  1803. BOOST_UBLAS_INLINE
  1804. const_iterator2 &operator -= (difference_type n) {
  1805. it2_ -= n;
  1806. return *this;
  1807. }
  1808. BOOST_UBLAS_INLINE
  1809. difference_type operator - (const const_iterator2 &it) const {
  1810. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1811. return it2_ - it.it2_;
  1812. }
  1813. // Dereference
  1814. BOOST_UBLAS_INLINE
  1815. const_reference operator * () const {
  1816. size_type i = index1 ();
  1817. size_type j = index2 ();
  1818. BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
  1819. BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
  1820. #ifdef BOOST_UBLAS_OWN_BANDED
  1821. size_type k = (std::max) (i, j);
  1822. size_type l = (*this) ().lower () + j - i;
  1823. if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
  1824. l < (*this) ().lower () + 1 + (*this) ().upper ())
  1825. return *it2_;
  1826. #else
  1827. size_type k = j;
  1828. size_type l = (*this) ().upper () + i - j;
  1829. if (k < (*this) ().size2 () &&
  1830. l < (*this) ().lower () + 1 + (*this) ().upper ())
  1831. return *it2_;
  1832. #endif
  1833. return (*this) () (i, j);
  1834. }
  1835. BOOST_UBLAS_INLINE
  1836. const_reference operator [] (difference_type n) const {
  1837. return *(*this + n);
  1838. }
  1839. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  1840. BOOST_UBLAS_INLINE
  1841. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1842. typename self_type::
  1843. #endif
  1844. const_iterator1 begin () const {
  1845. return (*this) ().find1 (1, 0, index2 ());
  1846. }
  1847. BOOST_UBLAS_INLINE
  1848. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1849. typename self_type::
  1850. #endif
  1851. const_iterator1 cbegin () const {
  1852. return begin ();
  1853. }
  1854. BOOST_UBLAS_INLINE
  1855. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1856. typename self_type::
  1857. #endif
  1858. const_iterator1 end () const {
  1859. return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
  1860. }
  1861. BOOST_UBLAS_INLINE
  1862. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1863. typename self_type::
  1864. #endif
  1865. const_iterator1 cend () const {
  1866. return end ();
  1867. }
  1868. BOOST_UBLAS_INLINE
  1869. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1870. typename self_type::
  1871. #endif
  1872. const_reverse_iterator1 rbegin () const {
  1873. return const_reverse_iterator1 (end ());
  1874. }
  1875. BOOST_UBLAS_INLINE
  1876. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1877. typename self_type::
  1878. #endif
  1879. const_reverse_iterator1 crbegin () const {
  1880. return rbegin ();
  1881. }
  1882. BOOST_UBLAS_INLINE
  1883. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1884. typename self_type::
  1885. #endif
  1886. const_reverse_iterator1 rend () const {
  1887. return const_reverse_iterator1 (begin ());
  1888. }
  1889. BOOST_UBLAS_INLINE
  1890. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1891. typename self_type::
  1892. #endif
  1893. const_reverse_iterator1 crend () const {
  1894. return rend ();
  1895. }
  1896. #endif
  1897. // Indices
  1898. BOOST_UBLAS_INLINE
  1899. size_type index1 () const {
  1900. return it2_.index1 ();
  1901. }
  1902. BOOST_UBLAS_INLINE
  1903. size_type index2 () const {
  1904. return it2_.index2 ();
  1905. }
  1906. // Assignment
  1907. BOOST_UBLAS_INLINE
  1908. const_iterator2 &operator = (const const_iterator2 &it) {
  1909. container_const_reference<self_type>::assign (&it ());
  1910. it2_ = it.it2_;
  1911. return *this;
  1912. }
  1913. // Comparison
  1914. BOOST_UBLAS_INLINE
  1915. bool operator == (const const_iterator2 &it) const {
  1916. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1917. return it2_ == it.it2_;
  1918. }
  1919. BOOST_UBLAS_INLINE
  1920. bool operator < (const const_iterator2 &it) const {
  1921. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1922. return it2_ < it.it2_;
  1923. }
  1924. private:
  1925. const_subiterator2_type it2_;
  1926. };
  1927. #endif
  1928. BOOST_UBLAS_INLINE
  1929. const_iterator2 begin2 () const {
  1930. return find2 (0, 0, 0);
  1931. }
  1932. BOOST_UBLAS_INLINE
  1933. const_iterator2 cbegin2 () const {
  1934. return begin2 ();
  1935. }
  1936. BOOST_UBLAS_INLINE
  1937. const_iterator2 end2 () const {
  1938. return find2 (0, 0, size2 ());
  1939. }
  1940. BOOST_UBLAS_INLINE
  1941. const_iterator2 cend2 () const {
  1942. return end2 ();
  1943. }
  1944. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1945. class iterator2:
  1946. public container_reference<banded_adaptor>,
  1947. public random_access_iterator_base<typename iterator_restrict_traits<
  1948. typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
  1949. iterator2, value_type> {
  1950. public:
  1951. typedef typename subiterator2_type::value_type value_type;
  1952. typedef typename subiterator2_type::difference_type difference_type;
  1953. typedef typename subiterator2_type::reference reference;
  1954. typedef typename subiterator2_type::pointer pointer;
  1955. typedef iterator1 dual_iterator_type;
  1956. typedef reverse_iterator1 dual_reverse_iterator_type;
  1957. // Construction and destruction
  1958. BOOST_UBLAS_INLINE
  1959. iterator2 ():
  1960. container_reference<self_type> (), it2_ () {}
  1961. BOOST_UBLAS_INLINE
  1962. iterator2 (self_type &m, const subiterator2_type &it2):
  1963. container_reference<self_type> (m), it2_ (it2) {}
  1964. // Arithmetic
  1965. BOOST_UBLAS_INLINE
  1966. iterator2 &operator ++ () {
  1967. ++ it2_;
  1968. return *this;
  1969. }
  1970. BOOST_UBLAS_INLINE
  1971. iterator2 &operator -- () {
  1972. -- it2_;
  1973. return *this;
  1974. }
  1975. BOOST_UBLAS_INLINE
  1976. iterator2 &operator += (difference_type n) {
  1977. it2_ += n;
  1978. return *this;
  1979. }
  1980. BOOST_UBLAS_INLINE
  1981. iterator2 &operator -= (difference_type n) {
  1982. it2_ -= n;
  1983. return *this;
  1984. }
  1985. BOOST_UBLAS_INLINE
  1986. difference_type operator - (const iterator2 &it) const {
  1987. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1988. return it2_ - it.it2_;
  1989. }
  1990. // Dereference
  1991. BOOST_UBLAS_INLINE
  1992. reference operator * () const {
  1993. size_type i = index1 ();
  1994. size_type j = index2 ();
  1995. BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
  1996. BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
  1997. #ifdef BOOST_UBLAS_OWN_BANDED
  1998. size_type k = (std::max) (i, j);
  1999. size_type l = (*this) ().lower () + j - i;
  2000. if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
  2001. l < (*this) ().lower () + 1 + (*this) ().upper ())
  2002. return *it2_;
  2003. #else
  2004. size_type k = j;
  2005. size_type l = (*this) ().upper () + i - j;
  2006. if (k < (*this) ().size2 () &&
  2007. l < (*this) ().lower () + 1 + (*this) ().upper ())
  2008. return *it2_;
  2009. #endif
  2010. return (*this) () (i, j);
  2011. }
  2012. BOOST_UBLAS_INLINE
  2013. reference operator [] (difference_type n) const {
  2014. return *(*this + n);
  2015. }
  2016. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  2017. BOOST_UBLAS_INLINE
  2018. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  2019. typename self_type::
  2020. #endif
  2021. iterator1 begin () const {
  2022. return (*this) ().find1 (1, 0, index2 ());
  2023. }
  2024. BOOST_UBLAS_INLINE
  2025. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  2026. typename self_type::
  2027. #endif
  2028. iterator1 end () const {
  2029. return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
  2030. }
  2031. BOOST_UBLAS_INLINE
  2032. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  2033. typename self_type::
  2034. #endif
  2035. reverse_iterator1 rbegin () const {
  2036. return reverse_iterator1 (end ());
  2037. }
  2038. BOOST_UBLAS_INLINE
  2039. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  2040. typename self_type::
  2041. #endif
  2042. reverse_iterator1 rend () const {
  2043. return reverse_iterator1 (begin ());
  2044. }
  2045. #endif
  2046. // Indices
  2047. BOOST_UBLAS_INLINE
  2048. size_type index1 () const {
  2049. return it2_.index1 ();
  2050. }
  2051. BOOST_UBLAS_INLINE
  2052. size_type index2 () const {
  2053. return it2_.index2 ();
  2054. }
  2055. // Assignment
  2056. BOOST_UBLAS_INLINE
  2057. iterator2 &operator = (const iterator2 &it) {
  2058. container_reference<self_type>::assign (&it ());
  2059. it2_ = it.it2_;
  2060. return *this;
  2061. }
  2062. // Comparison
  2063. BOOST_UBLAS_INLINE
  2064. bool operator == (const iterator2 &it) const {
  2065. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2066. return it2_ == it.it2_;
  2067. }
  2068. BOOST_UBLAS_INLINE
  2069. bool operator < (const iterator2 &it) const {
  2070. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2071. return it2_ < it.it2_;
  2072. }
  2073. private:
  2074. subiterator2_type it2_;
  2075. friend class const_iterator2;
  2076. };
  2077. #endif
  2078. BOOST_UBLAS_INLINE
  2079. iterator2 begin2 () {
  2080. return find2 (0, 0, 0);
  2081. }
  2082. BOOST_UBLAS_INLINE
  2083. iterator2 end2 () {
  2084. return find2 (0, 0, size2 ());
  2085. }
  2086. // Reverse iterators
  2087. BOOST_UBLAS_INLINE
  2088. const_reverse_iterator1 rbegin1 () const {
  2089. return const_reverse_iterator1 (end1 ());
  2090. }
  2091. BOOST_UBLAS_INLINE
  2092. const_reverse_iterator1 crbegin1 () const {
  2093. return rbegin1 ();
  2094. }
  2095. BOOST_UBLAS_INLINE
  2096. const_reverse_iterator1 rend1 () const {
  2097. return const_reverse_iterator1 (begin1 ());
  2098. }
  2099. BOOST_UBLAS_INLINE
  2100. const_reverse_iterator1 crend1 () const {
  2101. return rend1 ();
  2102. }
  2103. BOOST_UBLAS_INLINE
  2104. reverse_iterator1 rbegin1 () {
  2105. return reverse_iterator1 (end1 ());
  2106. }
  2107. BOOST_UBLAS_INLINE
  2108. reverse_iterator1 rend1 () {
  2109. return reverse_iterator1 (begin1 ());
  2110. }
  2111. BOOST_UBLAS_INLINE
  2112. const_reverse_iterator2 rbegin2 () const {
  2113. return const_reverse_iterator2 (end2 ());
  2114. }
  2115. BOOST_UBLAS_INLINE
  2116. const_reverse_iterator2 crbegin2 () const {
  2117. return rbegin2 ();
  2118. }
  2119. BOOST_UBLAS_INLINE
  2120. const_reverse_iterator2 rend2 () const {
  2121. return const_reverse_iterator2 (begin2 ());
  2122. }
  2123. BOOST_UBLAS_INLINE
  2124. const_reverse_iterator2 crend2 () const {
  2125. return rend2 ();
  2126. }
  2127. BOOST_UBLAS_INLINE
  2128. reverse_iterator2 rbegin2 () {
  2129. return reverse_iterator2 (end2 ());
  2130. }
  2131. BOOST_UBLAS_INLINE
  2132. reverse_iterator2 rend2 () {
  2133. return reverse_iterator2 (begin2 ());
  2134. }
  2135. private:
  2136. matrix_closure_type data_;
  2137. size_type lower_;
  2138. size_type upper_;
  2139. typedef const value_type const_value_type;
  2140. static const_value_type zero_;
  2141. };
  2142. // Specialization for temporary_traits
  2143. template <class M>
  2144. struct vector_temporary_traits< banded_adaptor<M> >
  2145. : vector_temporary_traits< M > {} ;
  2146. template <class M>
  2147. struct vector_temporary_traits< const banded_adaptor<M> >
  2148. : vector_temporary_traits< M > {} ;
  2149. template <class M>
  2150. struct matrix_temporary_traits< banded_adaptor<M> >
  2151. : matrix_temporary_traits< M > {} ;
  2152. template <class M>
  2153. struct matrix_temporary_traits< const banded_adaptor<M> >
  2154. : matrix_temporary_traits< M > {} ;
  2155. template<class M>
  2156. typename banded_adaptor<M>::const_value_type banded_adaptor<M>::zero_ = value_type/*zero*/();
  2157. /** \brief A diagonal matrix adaptator: convert a any matrix into a diagonal matrix expression
  2158. *
  2159. * For a \f$(m\times m)\f$-dimensional matrix, the \c diagonal_adaptor will provide a diagonal matrix
  2160. * with \f$0 \leq i < m\f$ and \f$0 \leq j < m\f$, if \f$i\neq j\f$ then \f$b_{i,j}=0\f$.
  2161. *
  2162. * Storage and location are based on those of the underlying matrix. This is important because
  2163. * a \c diagonal_adaptor does not copy the matrix data to a new place. Therefore, modifying values
  2164. * in a \c diagonal_adaptor matrix will also modify the underlying matrix too.
  2165. *
  2166. * \tparam M the type of matrix used to generate the diagonal matrix
  2167. */
  2168. template<class M>
  2169. class diagonal_adaptor:
  2170. public banded_adaptor<M> {
  2171. public:
  2172. typedef M matrix_type;
  2173. typedef banded_adaptor<M> adaptor_type;
  2174. // Construction and destruction
  2175. BOOST_UBLAS_INLINE
  2176. diagonal_adaptor ():
  2177. adaptor_type () {}
  2178. BOOST_UBLAS_INLINE
  2179. diagonal_adaptor (matrix_type &data):
  2180. adaptor_type (data) {}
  2181. BOOST_UBLAS_INLINE
  2182. ~diagonal_adaptor () {}
  2183. // Assignment
  2184. BOOST_UBLAS_INLINE
  2185. diagonal_adaptor &operator = (const diagonal_adaptor &m) {
  2186. adaptor_type::operator = (m);
  2187. return *this;
  2188. }
  2189. template<class AE>
  2190. BOOST_UBLAS_INLINE
  2191. diagonal_adaptor &operator = (const matrix_expression<AE> &ae) {
  2192. adaptor_type::operator = (ae);
  2193. return *this;
  2194. }
  2195. };
  2196. }}}
  2197. #endif