1 /* -*- c++ -*- (enables emacs c++ mode) */ 2 /*=========================================================================== 3 4 Copyright (C) 2002-2020 Yves Renard 5 6 This file is a part of GetFEM 7 8 GetFEM is free software; you can redistribute it and/or modify it 9 under the terms of the GNU Lesser General Public License as published 10 by the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version along with the GCC Runtime Library 12 Exception either version 3.1 or (at your option) any later version. 13 This program is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16 License and GCC Runtime Library Exception for more details. 17 You should have received a copy of the GNU Lesser General Public License 18 along with this program; if not, write to the Free Software Foundation, 19 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 20 21 As a special exception, you may use this file as it is a part of a free 22 software library without restriction. Specifically, if other files 23 instantiate templates or use macros or inline functions from this file, 24 or you compile this file and link it with other files to produce an 25 executable, this file does not by itself cause the resulting executable 26 to be covered by the GNU Lesser General Public License. This exception 27 does not however invalidate any other reasons why the executable file 28 might be covered by the GNU Lesser General Public License. 29 30 ===========================================================================*/ 31 32 /**@file gmm_sub_vector.h 33 @author Yves Renard <Yves.Renard@insa-lyon.fr> 34 @date October 13, 2002. 35 @brief Generic sub-vectors. 36 */ 37 38 #ifndef GMM_SUB_VECTOR_H__ 39 #define GMM_SUB_VECTOR_H__ 40 41 #include "gmm_interface.h" 42 #include "gmm_sub_index.h" 43 44 namespace gmm { 45 46 /* ********************************************************************* */ 47 /* sparse sub-vectors */ 48 /* ********************************************************************* */ 49 50 template <typename IT, typename MIT, typename SUBI> 51 struct sparse_sub_vector_iterator { 52 53 IT itb, itbe; 54 SUBI si; 55 56 typedef std::iterator_traits<IT> traits_type; 57 typedef typename traits_type::value_type value_type; 58 typedef typename traits_type::pointer pointer; 59 typedef typename traits_type::reference reference; 60 typedef typename traits_type::difference_type difference_type; 61 typedef std::bidirectional_iterator_tag iterator_category; 62 typedef size_t size_type; 63 typedef sparse_sub_vector_iterator<IT, MIT, SUBI> iterator; 64 indexsparse_sub_vector_iterator65 size_type index(void) const { return si.rindex(itb.index()); } 66 void forward(void); 67 void backward(void); 68 iterator &operator ++() 69 { ++itb; forward(); return *this; } 70 iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } 71 iterator &operator --() 72 { --itb; backward(); return *this; } 73 iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } 74 reference operator *() const { return *itb; } 75 76 bool operator ==(const iterator &i) const { return itb == i.itb; } 77 bool operator !=(const iterator &i) const { return !(i == *this); } 78 sparse_sub_vector_iteratorsparse_sub_vector_iterator79 sparse_sub_vector_iterator(void) {} sparse_sub_vector_iteratorsparse_sub_vector_iterator80 sparse_sub_vector_iterator(const IT &it, const IT &ite, const SUBI &s) 81 : itb(it), itbe(ite), si(s) { forward(); } sparse_sub_vector_iteratorsparse_sub_vector_iterator82 sparse_sub_vector_iterator 83 (const sparse_sub_vector_iterator<MIT, MIT, SUBI> &it) 84 : itb(it.itb), itbe(it.itbe), si(it.si) {} 85 sparse_sub_vector_iterator &operator = 86 (const sparse_sub_vector_iterator<MIT, MIT, SUBI> &it) 87 { itb = it.itb; itbe = it.itbe; si = it.si; return *this; } 88 89 }; 90 91 template <typename IT, typename MIT, typename SUBI> forward(void)92 void sparse_sub_vector_iterator<IT, MIT, SUBI>::forward(void) 93 { while(itb!=itbe && index()==size_type(-1)) { ++itb; } } 94 95 template <typename IT, typename MIT, typename SUBI> backward(void)96 void sparse_sub_vector_iterator<IT, MIT, SUBI>::backward(void) 97 { while(itb!=itbe && index()==size_type(-1)) --itb; } 98 99 template <typename PT, typename SUBI> struct sparse_sub_vector { 100 typedef sparse_sub_vector<PT, SUBI> this_type; 101 typedef typename std::iterator_traits<PT>::value_type V; 102 typedef V * CPT; 103 typedef typename select_ref<typename linalg_traits<V>::const_iterator, 104 typename linalg_traits<V>::iterator, PT>::ref_type iterator; 105 typedef typename linalg_traits<this_type>::reference reference; 106 typedef typename linalg_traits<this_type>::porigin_type porigin_type; 107 108 iterator begin_, end_; 109 porigin_type origin; 110 SUBI si; 111 sizesparse_sub_vector112 size_type size(void) const { return si.size(); } 113 114 reference operator[](size_type i) const 115 { return linalg_traits<V>::access(origin, begin_, end_, si.index(i)); } 116 sparse_sub_vectorsparse_sub_vector117 sparse_sub_vector(V &v, const SUBI &s) : begin_(vect_begin(v)), 118 end_(vect_end(v)), origin(linalg_origin(v)), si(s) {} sparse_sub_vectorsparse_sub_vector119 sparse_sub_vector(const V &v, const SUBI &s) 120 : begin_(vect_begin(const_cast<V &>(v))), 121 end_(vect_end(const_cast<V &>(v))), 122 origin(linalg_origin(const_cast<V &>(v))), si(s) {} sparse_sub_vectorsparse_sub_vector123 sparse_sub_vector() {} sparse_sub_vectorsparse_sub_vector124 sparse_sub_vector(const sparse_sub_vector<CPT, SUBI> &cr) 125 : begin_(cr.begin_),end_(cr.end_),origin(cr.origin), si(cr.si) {} 126 }; 127 128 template <typename IT, typename MIT, typename SUBI, typename ORG, 129 typename PT> inline set_to_begin(sparse_sub_vector_iterator<IT,MIT,SUBI> & it,ORG o,sparse_sub_vector<PT,SUBI> *,linalg_modifiable)130 void set_to_begin(sparse_sub_vector_iterator<IT, MIT, SUBI> &it, 131 ORG o, sparse_sub_vector<PT, SUBI> *, 132 linalg_modifiable) { 133 typedef sparse_sub_vector<PT, SUBI> VECT; 134 typedef typename linalg_traits<VECT>::V_reference ref_t; 135 set_to_begin(it.itb, o, typename linalg_traits<VECT>::pV(), ref_t()); 136 set_to_end(it.itbe, o, typename linalg_traits<VECT>::pV(), ref_t()); 137 it.forward(); 138 } 139 template <typename IT, typename MIT, typename SUBI, typename ORG, 140 typename PT> inline set_to_begin(sparse_sub_vector_iterator<IT,MIT,SUBI> & it,ORG o,const sparse_sub_vector<PT,SUBI> *,linalg_modifiable)141 void set_to_begin(sparse_sub_vector_iterator<IT, MIT, SUBI> &it, 142 ORG o, const sparse_sub_vector<PT, SUBI> *, 143 linalg_modifiable) { 144 typedef sparse_sub_vector<PT, SUBI> VECT; 145 typedef typename linalg_traits<VECT>::V_reference ref_t; 146 set_to_begin(it.itb, o, typename linalg_traits<VECT>::pV(), ref_t()); 147 set_to_end(it.itbe, o, typename linalg_traits<VECT>::pV(), ref_t()); 148 it.forward(); 149 } 150 151 template <typename IT, typename MIT, typename SUBI, typename ORG, 152 typename PT> inline set_to_end(sparse_sub_vector_iterator<IT,MIT,SUBI> & it,ORG o,sparse_sub_vector<PT,SUBI> *,linalg_modifiable)153 void set_to_end(sparse_sub_vector_iterator<IT, MIT, SUBI> &it, 154 ORG o, sparse_sub_vector<PT, SUBI> *, linalg_modifiable) { 155 typedef sparse_sub_vector<PT, SUBI> VECT; 156 typedef typename linalg_traits<VECT>::V_reference ref_t; 157 set_to_end(it.itb, o, typename linalg_traits<VECT>::pV(), ref_t()); 158 set_to_end(it.itbe, o, typename linalg_traits<VECT>::pV(), ref_t()); 159 it.forward(); 160 } 161 template <typename IT, typename MIT, typename SUBI, typename ORG, 162 typename PT> inline set_to_end(sparse_sub_vector_iterator<IT,MIT,SUBI> & it,ORG o,const sparse_sub_vector<PT,SUBI> *,linalg_modifiable)163 void set_to_end(sparse_sub_vector_iterator<IT, MIT, SUBI> &it, 164 ORG o, const sparse_sub_vector<PT, SUBI> *, 165 linalg_modifiable) { 166 typedef sparse_sub_vector<PT, SUBI> VECT; 167 typedef typename linalg_traits<VECT>::V_reference ref_t; 168 set_to_end(it.itb, o, typename linalg_traits<VECT>::pV(), ref_t()); 169 set_to_end(it.itbe, o, typename linalg_traits<VECT>::pV(), ref_t()); 170 it.forward(); 171 } 172 173 template <typename PT, typename SUBI> 174 struct linalg_traits<sparse_sub_vector<PT, SUBI> > { 175 typedef sparse_sub_vector<PT, SUBI> this_type; 176 typedef this_type * pthis_type; 177 typedef PT pV; 178 typedef typename std::iterator_traits<PT>::value_type V; 179 typedef typename linalg_and<typename index_is_sorted<SUBI>::bool_type, 180 typename linalg_traits<V>::index_sorted>::bool_type index_sorted; 181 typedef typename linalg_traits<V>::is_reference V_reference; 182 typedef typename linalg_traits<V>::origin_type origin_type; 183 typedef typename select_ref<const origin_type *, origin_type *, 184 PT>::ref_type porigin_type; 185 typedef typename which_reference<PT>::is_reference is_reference; 186 typedef abstract_vector linalg_type; 187 typedef typename linalg_traits<V>::value_type value_type; 188 typedef typename select_ref<value_type, typename 189 linalg_traits<V>::reference, PT>::ref_type reference; 190 typedef typename select_ref<typename linalg_traits<V>::const_iterator, 191 typename linalg_traits<V>::iterator, PT>::ref_type pre_iterator; 192 typedef typename select_ref<abstract_null_type, 193 sparse_sub_vector_iterator<pre_iterator, pre_iterator, SUBI>, 194 PT>::ref_type iterator; 195 typedef sparse_sub_vector_iterator<typename linalg_traits<V> 196 ::const_iterator, pre_iterator, SUBI> const_iterator; 197 typedef abstract_sparse storage_type; 198 static size_type size(const this_type &v) { return v.size(); } 199 static iterator begin(this_type &v) { 200 iterator it; 201 it.itb = v.begin_; it.itbe = v.end_; it.si = v.si; 202 if (!is_const_reference(is_reference())) 203 set_to_begin(it, v.origin, pthis_type(), is_reference()); 204 else it.forward(); 205 return it; 206 } 207 static const_iterator begin(const this_type &v) { 208 const_iterator it; it.itb = v.begin_; it.itbe = v.end_; it.si = v.si; 209 if (!is_const_reference(is_reference())) 210 { set_to_begin(it, v.origin, pthis_type(), is_reference()); } 211 else it.forward(); 212 return it; 213 } 214 static iterator end(this_type &v) { 215 iterator it; 216 it.itb = v.end_; it.itbe = v.end_; it.si = v.si; 217 if (!is_const_reference(is_reference())) 218 set_to_end(it, v.origin, pthis_type(), is_reference()); 219 else it.forward(); 220 return it; 221 } 222 static const_iterator end(const this_type &v) { 223 const_iterator it; it.itb = v.end_; it.itbe = v.end_; it.si = v.si; 224 if (!is_const_reference(is_reference())) 225 set_to_end(it, v.origin, pthis_type(), is_reference()); 226 else it.forward(); 227 return it; 228 } 229 static origin_type* origin(this_type &v) { return v.origin; } 230 static const origin_type* origin(const this_type &v) { return v.origin; } 231 static void clear(origin_type* o, const iterator &begin_, 232 const iterator &end_) { 233 std::deque<size_type> ind; 234 iterator it = begin_; 235 for (; it != end_; ++it) ind.push_front(it.index()); 236 for (; !(ind.empty()); ind.pop_back()) 237 access(o, begin_, end_, ind.back()) = value_type(0); 238 } 239 static void do_clear(this_type &v) { clear(v.origin, begin(v), end(v)); } 240 static value_type access(const origin_type *o, const const_iterator &it, 241 const const_iterator &ite, size_type i) 242 { return linalg_traits<V>::access(o, it.itb, ite.itb, it.si.index(i)); } 243 static reference access(origin_type *o, const iterator &it, 244 const iterator &ite, size_type i) 245 { return linalg_traits<V>::access(o, it.itb, ite.itb, it.si.index(i)); } 246 }; 247 248 template <typename PT, typename SUBI> std::ostream &operator << 249 (std::ostream &o, const sparse_sub_vector<PT, SUBI>& m) 250 { gmm::write(o,m); return o; } 251 252 /* ********************************************************************* */ 253 /* skyline sub-vectors */ 254 /* ********************************************************************* */ 255 256 template <typename IT, typename MIT, typename SUBI> 257 struct skyline_sub_vector_iterator { 258 259 IT itb; 260 SUBI si; 261 262 typedef std::iterator_traits<IT> traits_type; 263 typedef typename traits_type::value_type value_type; 264 typedef typename traits_type::pointer pointer; 265 typedef typename traits_type::reference reference; 266 typedef typename traits_type::difference_type difference_type; 267 typedef std::bidirectional_iterator_tag iterator_category; 268 typedef size_t size_type; 269 typedef skyline_sub_vector_iterator<IT, MIT, SUBI> iterator; 270 271 size_type index(void) const 272 { return (itb.index() - si.min + si.step() - 1) / si.step(); } 273 void backward(void); 274 iterator &operator ++() 275 { itb += si.step(); return *this; } 276 iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } 277 iterator &operator --() 278 { itb -= si.step(); return *this; } 279 iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } 280 281 iterator &operator +=(difference_type i) 282 { itb += si.step() * i; return *this; } 283 iterator &operator -=(difference_type i) 284 { itb -= si.step() * i; return *this; } 285 iterator operator +(difference_type i) const 286 { iterator ii = *this; return (ii += i); } 287 iterator operator -(difference_type i) const 288 { iterator ii = *this; return (ii -= i); } 289 difference_type operator -(const iterator &i) const 290 { return (itb - i.itb) / si.step(); } 291 292 reference operator *() const { return *itb; } 293 reference operator [](int ii) { return *(itb + ii * si.step()); } 294 295 bool operator ==(const iterator &i) const { return index() == i.index();} 296 bool operator !=(const iterator &i) const { return !(i == *this); } 297 bool operator < (const iterator &i) const { return index() < i.index();} 298 299 skyline_sub_vector_iterator(void) {} 300 skyline_sub_vector_iterator(const IT &it, const SUBI &s) 301 : itb(it), si(s) {} 302 skyline_sub_vector_iterator(const skyline_sub_vector_iterator<MIT, MIT, 303 SUBI> &it) : itb(it.itb), si(it.si) {} 304 }; 305 306 template <typename IT, typename SUBI> 307 void update_for_sub_skyline(IT &it, IT &ite, const SUBI &si) { 308 if (it.index() >= si.max || ite.index() <= si.min) { it = ite; return; } 309 ptrdiff_t dec1 = si.min - it.index(), dec2 = ite.index() - si.max; 310 it += (dec1 < 0) ? ((si.step()-((-dec1) % si.step())) % si.step()) : dec1; 311 ite -= (dec2 < 0) ? -((-dec2) % si.step()) : dec2; 312 } 313 314 template <typename PT, typename SUBI> struct skyline_sub_vector { 315 typedef skyline_sub_vector<PT, SUBI> this_type; 316 typedef typename std::iterator_traits<PT>::value_type V; 317 typedef V * pV; 318 typedef typename select_ref<typename linalg_traits<V>::const_iterator, 319 typename linalg_traits<V>::iterator, PT>::ref_type iterator; 320 typedef typename linalg_traits<this_type>::reference reference; 321 typedef typename linalg_traits<this_type>::porigin_type porigin_type; 322 323 iterator begin_, end_; 324 porigin_type origin; 325 SUBI si; 326 327 size_type size(void) const { return si.size(); } 328 329 reference operator[](size_type i) const 330 { return linalg_traits<V>::access(origin, begin_, end_, si.index(i)); } 331 332 skyline_sub_vector(V &v, const SUBI &s) : begin_(vect_begin(v)), 333 end_(vect_end(v)), origin(linalg_origin(v)), si(s) { 334 update_for_sub_skyline(begin_, end_, si); 335 } 336 skyline_sub_vector(const V &v, const SUBI &s) 337 : begin_(vect_begin(const_cast<V &>(v))), 338 end_(vect_end(const_cast<V &>(v))), 339 origin(linalg_origin(const_cast<V &>(v))), si(s) { 340 update_for_sub_skyline(begin_, end_, si); 341 } 342 skyline_sub_vector() {} 343 skyline_sub_vector(const skyline_sub_vector<pV, SUBI> &cr) 344 : begin_(cr.begin_),end_(cr.end_),origin(cr.origin), si(cr.si) {} 345 }; 346 347 template <typename IT, typename MIT, typename SUBI, typename ORG, 348 typename PT> inline 349 void set_to_begin(skyline_sub_vector_iterator<IT, MIT, SUBI> &it, 350 ORG o, skyline_sub_vector<PT, SUBI> *, 351 linalg_modifiable) { 352 typedef skyline_sub_vector<PT, SUBI> VECT; 353 typedef typename linalg_traits<VECT>::V_reference ref_t; 354 IT itbe = it.itb; 355 set_to_begin(it.itb, o, typename linalg_traits<VECT>::pV(), ref_t()); 356 set_to_end(itbe, o, typename linalg_traits<VECT>::pV(), ref_t()); 357 update_for_sub_skyline(it.itb, itbe, it.si); 358 } 359 template <typename IT, typename MIT, typename SUBI, typename ORG, 360 typename PT> inline 361 void set_to_begin(skyline_sub_vector_iterator<IT, MIT, SUBI> &it, 362 ORG o, const skyline_sub_vector<PT, SUBI> *, 363 linalg_modifiable) { 364 typedef skyline_sub_vector<PT, SUBI> VECT; 365 typedef typename linalg_traits<VECT>::V_reference ref_t; 366 IT itbe = it.itb; 367 set_to_begin(it.itb, o, typename linalg_traits<VECT>::pV(), ref_t()); 368 set_to_end(itbe, o, typename linalg_traits<VECT>::pV(), ref_t()); 369 update_for_sub_skyline(it.itb, itbe, it.si); 370 } 371 372 template <typename IT, typename MIT, typename SUBI, typename ORG, 373 typename PT> inline 374 void set_to_end(skyline_sub_vector_iterator<IT, MIT, SUBI> &it, 375 ORG o, skyline_sub_vector<PT, SUBI> *, 376 linalg_modifiable) { 377 typedef skyline_sub_vector<PT, SUBI> VECT; 378 typedef typename linalg_traits<VECT>::V_reference ref_t; 379 IT itb = it.itb; 380 set_to_begin(itb, o, typename linalg_traits<VECT>::pV(), ref_t()); 381 set_to_end(it.itb, o, typename linalg_traits<VECT>::pV(), ref_t()); 382 update_for_sub_skyline(itb, it.itb, it.si); 383 } 384 template <typename IT, typename MIT, typename SUBI, typename ORG, 385 typename PT> inline 386 void set_to_end(skyline_sub_vector_iterator<IT, MIT, SUBI> &it, 387 ORG o, const skyline_sub_vector<PT, SUBI> *, 388 linalg_modifiable) { 389 typedef skyline_sub_vector<PT, SUBI> VECT; 390 typedef typename linalg_traits<VECT>::V_reference ref_t; 391 IT itb = it.itb; 392 set_to_begin(itb, o, typename linalg_traits<VECT>::pV(), ref_t()); 393 set_to_end(it.itb, o, typename linalg_traits<VECT>::pV(), ref_t()); 394 update_for_sub_skyline(itb, it.itb, it.si); 395 } 396 397 398 template <typename PT, typename SUBI> 399 struct linalg_traits<skyline_sub_vector<PT, SUBI> > { 400 typedef skyline_sub_vector<PT, SUBI> this_type; 401 typedef this_type *pthis_type; 402 typedef typename std::iterator_traits<PT>::value_type V; 403 typedef typename linalg_traits<V>::is_reference V_reference; 404 typedef typename linalg_traits<V>::origin_type origin_type; 405 typedef typename select_ref<const origin_type *, origin_type *, 406 PT>::ref_type porigin_type; 407 typedef V * pV; 408 typedef typename which_reference<PT>::is_reference is_reference; 409 typedef abstract_vector linalg_type; 410 typedef typename linalg_traits<V>::value_type value_type; 411 typedef typename select_ref<value_type, typename 412 linalg_traits<V>::reference, PT>::ref_type reference; 413 typedef typename linalg_traits<V>::const_iterator const_V_iterator; 414 typedef typename linalg_traits<V>::iterator V_iterator; 415 typedef typename select_ref<const_V_iterator, V_iterator, 416 PT>::ref_type pre_iterator; 417 typedef typename select_ref<abstract_null_type, 418 skyline_sub_vector_iterator<pre_iterator, pre_iterator, SUBI>, 419 PT>::ref_type iterator; 420 typedef skyline_sub_vector_iterator<const_V_iterator, pre_iterator, SUBI> 421 const_iterator; 422 typedef abstract_skyline storage_type; 423 typedef linalg_true index_sorted; 424 static size_type size(const this_type &v) { return v.size(); } 425 static iterator begin(this_type &v) { 426 iterator it; 427 it.itb = v.begin_; it.si = v.si; 428 if (!is_const_reference(is_reference())) 429 set_to_begin(it, v.origin, pthis_type(), is_reference()); 430 return it; 431 } 432 static const_iterator begin(const this_type &v) { 433 const_iterator it; it.itb = v.begin_; it.si = v.si; 434 if (!is_const_reference(is_reference())) 435 { set_to_begin(it, v.origin, pthis_type(), is_reference()); } 436 return it; 437 } 438 static iterator end(this_type &v) { 439 iterator it; 440 it.itb = v.end_; it.si = v.si; 441 if (!is_const_reference(is_reference())) 442 set_to_end(it, v.origin, pthis_type(), is_reference()); 443 return it; 444 } 445 static const_iterator end(const this_type &v) { 446 const_iterator it; it.itb = v.end_; it.si = v.si; 447 if (!is_const_reference(is_reference())) 448 set_to_end(it, v.origin, pthis_type(), is_reference()); 449 return it; 450 } 451 static origin_type* origin(this_type &v) { return v.origin; } 452 static const origin_type* origin(const this_type &v) { return v.origin; } 453 static void clear(origin_type*, const iterator &it, const iterator &ite) 454 { std::fill(it, ite, value_type(0)); } 455 static void do_clear(this_type &v) { clear(v.origin, begin(v), end(v)); } 456 static value_type access(const origin_type *o, const const_iterator &it, 457 const const_iterator &ite, size_type i) 458 { return linalg_traits<V>::access(o, it.itb, ite.itb, it.si.index(i)); } 459 static reference access(origin_type *o, const iterator &it, 460 const iterator &ite, size_type i) 461 { return linalg_traits<V>::access(o, it.itb, ite.itb, it.si.index(i)); } 462 }; 463 464 template <typename PT, typename SUBI> std::ostream &operator << 465 (std::ostream &o, const skyline_sub_vector<PT, SUBI>& m) 466 { gmm::write(o,m); return o; } 467 468 /* ******************************************************************** */ 469 /* sub vector. */ 470 /* ******************************************************************** */ 471 /* sub_vector_type<PT, SUBI>::vector_type is the sub vector type */ 472 /* returned by sub_vector(v, sub_index) */ 473 /************************************************************************/ 474 475 template <typename PT, typename SUBI, typename st_type> struct svrt_ir { 476 typedef abstract_null_type vector_type; 477 }; 478 479 template <typename PT> 480 struct svrt_ir<PT, sub_index, abstract_dense> { 481 typedef typename std::iterator_traits<PT>::value_type V; 482 typedef typename vect_ref_type<PT, V>::iterator iterator; 483 typedef tab_ref_index_ref_with_origin<iterator, 484 sub_index::const_iterator, V> vector_type; 485 }; 486 487 template <typename PT> 488 struct svrt_ir<PT, unsorted_sub_index, abstract_dense> { 489 typedef typename std::iterator_traits<PT>::value_type V; 490 typedef typename vect_ref_type<PT, V>::iterator iterator; 491 typedef tab_ref_index_ref_with_origin<iterator, 492 unsorted_sub_index::const_iterator, V> vector_type; 493 }; 494 495 template <typename PT> 496 struct svrt_ir<PT, sub_interval, abstract_dense> { 497 typedef typename std::iterator_traits<PT>::value_type V; 498 typedef typename vect_ref_type<PT, V>::iterator iterator; 499 typedef tab_ref_with_origin<iterator, V> vector_type; 500 }; 501 502 template <typename PT> 503 struct svrt_ir<PT, sub_slice, abstract_dense> { 504 typedef typename std::iterator_traits<PT>::value_type V; 505 typedef typename vect_ref_type<PT, V>::iterator iterator; 506 typedef tab_ref_reg_spaced_with_origin<iterator, V> vector_type; 507 }; 508 509 template <typename PT, typename SUBI> 510 struct svrt_ir<PT, SUBI, abstract_skyline> { 511 typedef skyline_sub_vector<PT, SUBI> vector_type; 512 }; 513 514 template <typename PT> 515 struct svrt_ir<PT, sub_index, abstract_skyline> { 516 typedef sparse_sub_vector<PT, sub_index> vector_type; 517 }; 518 519 template <typename PT> 520 struct svrt_ir<PT, unsorted_sub_index, abstract_skyline> { 521 typedef sparse_sub_vector<PT, unsorted_sub_index> vector_type; 522 }; 523 524 525 template <typename PT, typename SUBI> 526 struct svrt_ir<PT, SUBI, abstract_sparse> { 527 typedef sparse_sub_vector<PT, SUBI> vector_type; 528 }; 529 530 template <typename PT, typename SUBI> 531 struct sub_vector_type { 532 typedef typename std::iterator_traits<PT>::value_type V; 533 typedef typename svrt_ir<PT, SUBI, 534 typename linalg_traits<V>::storage_type>::vector_type vector_type; 535 }; 536 537 template <typename V, typename SUBI> 538 typename select_return< 539 typename sub_vector_type<const V *, SUBI>::vector_type, 540 typename sub_vector_type<V *, SUBI>::vector_type, const V *>::return_type 541 sub_vector(const V &v, const SUBI &si) { 542 GMM_ASSERT2(si.last() <= vect_size(v), 543 "sub vector too large, " << si.last() << " > " << vect_size(v)); 544 return typename select_return< 545 typename sub_vector_type<const V *, SUBI>::vector_type, 546 typename sub_vector_type<V *, SUBI>::vector_type, const V *>::return_type 547 (linalg_cast(v), si); 548 } 549 550 template <typename V, typename SUBI> 551 typename select_return< 552 typename sub_vector_type<const V *, SUBI>::vector_type, 553 typename sub_vector_type<V *, SUBI>::vector_type, V *>::return_type 554 sub_vector(V &v, const SUBI &si) { 555 GMM_ASSERT2(si.last() <= vect_size(v), 556 "sub vector too large, " << si.last() << " > " << vect_size(v)); 557 return typename select_return< 558 typename sub_vector_type<const V *, SUBI>::vector_type, 559 typename sub_vector_type<V *, SUBI>::vector_type, V *>::return_type 560 (linalg_cast(v), si); 561 } 562 563 } 564 565 #endif // GMM_SUB_VECTOR_H__ 566