37 #ifndef GMM_SUB_MATRIX_H__
38 #define GMM_SUB_MATRIX_H__
48 template <
typename PT,
typename SUBI1,
typename SUBI2>
49 struct gen_sub_row_matrix {
50 typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
51 typedef typename std::iterator_traits<PT>::value_type M;
53 typedef typename std::iterator_traits<PT>::reference ref_M;
54 typedef typename select_ref<typename linalg_traits<M>::const_row_iterator,
55 typename linalg_traits<M>::row_iterator,
58 typedef typename linalg_traits<this_type>::reference reference;
59 typedef typename linalg_traits<this_type>::porigin_type porigin_type;
67 {
return linalg_traits<M>::access(begin_ + si1.index(i), si2.index(j)); }
69 size_type nrows()
const {
return si1.size(); }
70 size_type ncols()
const {
return si2.size(); }
72 gen_sub_row_matrix(ref_M m,
const SUBI1 &s1,
const SUBI2 &s2)
73 : si1(s1), si2(s2), begin_(mat_row_begin(m)),
74 origin(linalg_origin(m)) {}
75 gen_sub_row_matrix() {}
76 gen_sub_row_matrix(
const gen_sub_row_matrix<CPT, SUBI1, SUBI2> &cr) :
77 si1(cr.si1), si2(cr.si2), begin_(cr.begin_),origin(cr.origin) {}
80 template <
typename PT,
typename SUBI1,
typename SUBI2>
81 struct gen_sub_row_matrix_iterator {
82 typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
83 typedef typename modifiable_pointer<PT>::pointer MPT;
84 typedef typename const_pointer<PT>::pointer CPT;
85 typedef typename std::iterator_traits<PT>::value_type M;
86 typedef typename select_ref<typename linalg_traits<M>::const_row_iterator,
87 typename linalg_traits<M>::row_iterator,
90 typedef value_type *pointer;
91 typedef ptrdiff_t difference_type;
93 typedef std::random_access_iterator_tag iterator_category;
94 typedef gen_sub_row_matrix_iterator<PT, SUBI1, SUBI2> iterator;
101 iterator operator ++(
int) { iterator tmp = *
this; ii++;
return tmp; }
102 iterator operator --(
int) { iterator tmp = *
this; ii--;
return tmp; }
103 iterator &operator ++() { ii++;
return *
this; }
104 iterator &operator --() { ii--;
return *
this; }
105 iterator &operator +=(difference_type i) { ii += i;
return *
this; }
106 iterator &operator -=(difference_type i) { ii -= i;
return *
this; }
108 { iterator itt = *
this;
return (itt += i); }
110 { iterator itt = *
this;
return (itt -= i); }
111 difference_type
operator -(
const iterator &i)
const {
return ii - i.ii; }
113 value_type operator *()
const {
return it + si1.index(ii); }
114 value_type operator [](
int i) {
return it + si1.index(ii+i); }
116 bool operator ==(
const iterator &i)
const {
return (ii == i.ii); }
117 bool operator !=(
const iterator &i)
const {
return !(i == *
this); }
118 bool operator < (
const iterator &i)
const {
return (ii < i.ii); }
119 bool operator > (
const iterator &i)
const {
return (ii > i.ii); }
120 bool operator >=(
const iterator &i)
const {
return (ii >= i.ii); }
122 gen_sub_row_matrix_iterator() {}
124 gen_sub_row_matrix_iterator
125 (
const gen_sub_row_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
126 : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
127 gen_sub_row_matrix_iterator
128 (
const gen_sub_row_matrix_iterator<CPT, SUBI1, SUBI2> &itm)
129 : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
130 gen_sub_row_matrix_iterator(
const value_type &iter,
const SUBI1 &s1,
132 : it(iter), si1(s1), si2(s2), ii(i) { }
135 template <
typename PT,
typename SUBI1,
typename SUBI2>
136 struct linalg_traits<gen_sub_row_matrix<PT, SUBI1, SUBI2> > {
137 typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
138 typedef typename std::iterator_traits<PT>::value_type M;
139 typedef typename which_reference<PT>::is_reference is_reference;
140 typedef abstract_matrix linalg_type;
141 typedef typename linalg_traits<M>::origin_type origin_type;
142 typedef typename select_ref<
const origin_type *,
146 typedef typename linalg_traits<M>::value_type value_type;
147 typedef typename select_ref<value_type,
148 typename linalg_traits<M>::reference,
151 typedef abstract_null_type sub_col_type;
152 typedef abstract_null_type col_iterator;
153 typedef abstract_null_type const_sub_col_type;
154 typedef abstract_null_type const_col_iterator;
155 typedef typename sub_vector_type
156 <
const typename org_type<typename linalg_traits<M>
157 ::const_sub_row_type>::t *,
160 typedef typename select_ref
162 typename sub_vector_type<
typename org_type
163 <
typename linalg_traits<M>
164 ::sub_row_type>::t *,
168 typedef gen_sub_row_matrix_iterator<typename const_pointer<PT>::pointer,
171 typedef typename select_ref<abstract_null_type,
172 gen_sub_row_matrix_iterator<PT, SUBI1, SUBI2>,
175 typedef typename linalg_traits<const_sub_row_type>::storage_type
177 typedef row_major sub_orientation;
178 typedef linalg_true index_sorted;
180 static size_type nrows(
const this_type &m) {
return m.nrows(); }
182 static size_type ncols(
const this_type &m) {
return m.ncols(); }
184 static const_sub_row_type row(
const const_row_iterator &it)
185 {
return const_sub_row_type(linalg_traits<M>::row(*it), it.si2); }
187 static sub_row_type row(
const row_iterator &it)
188 {
return sub_row_type(linalg_traits<M>::row(*it), it.si2); }
190 static const_row_iterator row_begin(
const this_type &m)
191 {
return const_row_iterator(m.begin_, m.si1, m.si2, 0); }
193 static row_iterator row_begin(this_type &m)
194 {
return row_iterator(m.begin_, m.si1, m.si2, 0); }
196 static const_row_iterator row_end(
const this_type &m)
197 {
return const_row_iterator(m.begin_, m.si1, m.si2, m.nrows()); }
199 static row_iterator row_end(this_type &m)
200 {
return row_iterator(m.begin_, m.si1, m.si2, m.nrows()); }
202 static origin_type* origin(this_type &v) {
return v.origin; }
204 static const origin_type* origin(
const this_type &v) {
return v.origin; }
206 static void do_clear(this_type &m) {
207 row_iterator it = mat_row_begin(m), ite = mat_row_end(m);
208 for (; it != ite; ++it)
clear(row(it));
211 static value_type access(
const const_row_iterator &itrow,
size_type i)
212 {
return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
214 static reference access(
const row_iterator &itrow,
size_type i)
215 {
return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
218 template <
typename PT,
typename SUBI1,
typename SUBI2>
219 std::ostream &operator <<(std::ostream &o,
220 const gen_sub_row_matrix<PT, SUBI1, SUBI2>& m)
221 { gmm::write(o,m);
return o; }
228 template <
typename PT,
typename SUBI1,
typename SUBI2>
229 struct gen_sub_col_matrix {
230 typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
231 typedef typename std::iterator_traits<PT>::value_type M;
233 typedef typename std::iterator_traits<PT>::reference ref_M;
234 typedef typename select_ref<typename linalg_traits<M>::const_col_iterator,
235 typename linalg_traits<M>::col_iterator,
238 typedef typename linalg_traits<this_type>::reference reference;
239 typedef typename linalg_traits<this_type>::porigin_type porigin_type;
247 {
return linalg_traits<M>::access(begin_ + si2.index(j), si1.index(i)); }
249 size_type nrows()
const {
return si1.size(); }
250 size_type ncols()
const {
return si2.size(); }
252 gen_sub_col_matrix(ref_M m,
const SUBI1 &s1,
const SUBI2 &s2)
253 : si1(s1), si2(s2), begin_(mat_col_begin(m)),
254 origin(linalg_origin(m)) {}
255 gen_sub_col_matrix() {}
256 gen_sub_col_matrix(
const gen_sub_col_matrix<CPT, SUBI1, SUBI2> &cr) :
257 si1(cr.si1), si2(cr.si2), begin_(cr.begin_),origin(cr.origin) {}
260 template <
typename PT,
typename SUBI1,
typename SUBI2>
261 struct gen_sub_col_matrix_iterator {
262 typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
263 typedef typename modifiable_pointer<PT>::pointer MPT;
264 typedef typename const_pointer<PT>::pointer CPT;
265 typedef typename std::iterator_traits<PT>::value_type M;
266 typedef typename select_ref<typename linalg_traits<M>::const_col_iterator,
267 typename linalg_traits<M>::col_iterator,
270 typedef value_type *pointer;
271 typedef ptrdiff_t difference_type;
273 typedef std::random_access_iterator_tag iterator_category;
274 typedef gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2> iterator;
281 iterator operator ++(
int) { iterator tmp = *
this; ii++;
return tmp; }
282 iterator operator --(
int) { iterator tmp = *
this; ii--;
return tmp; }
283 iterator &operator ++() { ii++;
return *
this; }
284 iterator &operator --() { ii--;
return *
this; }
285 iterator &operator +=(difference_type i) { ii += i;
return *
this; }
286 iterator &operator -=(difference_type i) { ii -= i;
return *
this; }
288 { iterator itt = *
this;
return (itt += i); }
290 { iterator itt = *
this;
return (itt -= i); }
291 difference_type
operator -(
const iterator &i)
const {
return ii - i.ii; }
293 value_type operator *()
const {
return it + si2.index(ii); }
294 value_type operator [](
int i) {
return it + si2.index(ii+i); }
296 bool operator ==(
const iterator &i)
const {
return (ii == i.ii); }
297 bool operator !=(
const iterator &i)
const {
return !(i == *
this); }
298 bool operator < (
const iterator &i)
const {
return (ii < i.ii); }
299 bool operator > (
const iterator &i)
const {
return (ii > i.ii); }
300 bool operator >=(
const iterator &i)
const {
return (ii >= i.ii); }
302 gen_sub_col_matrix_iterator() {}
304 gen_sub_col_matrix_iterator
305 (
const gen_sub_col_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
306 : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
307 gen_sub_col_matrix_iterator
308 (
const gen_sub_col_matrix_iterator<CPT, SUBI1, SUBI2> &itm)
309 : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
310 gen_sub_col_matrix_iterator(
const value_type &iter,
const SUBI1 &s1,
312 : it(iter), si1(s1), si2(s2), ii(i) { }
315 template <
typename PT,
typename SUBI1,
typename SUBI2>
316 struct linalg_traits<gen_sub_col_matrix<PT, SUBI1, SUBI2> > {
317 typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
318 typedef typename std::iterator_traits<PT>::value_type M;
319 typedef typename which_reference<PT>::is_reference is_reference;
320 typedef abstract_matrix linalg_type;
321 typedef typename linalg_traits<M>::origin_type origin_type;
322 typedef typename select_ref<
const origin_type *,
326 typedef typename linalg_traits<M>::value_type value_type;
327 typedef typename select_ref<value_type,
328 typename linalg_traits<M>::reference,
331 typedef abstract_null_type sub_row_type;
332 typedef abstract_null_type row_iterator;
333 typedef abstract_null_type const_sub_row_type;
334 typedef abstract_null_type const_row_iterator;
335 typedef typename sub_vector_type
336 <
const typename org_type<typename linalg_traits<M>
337 ::const_sub_col_type>::t *,
340 typedef typename select_ref
342 typename sub_vector_type<
typename org_type
343 <
typename linalg_traits<M>
344 ::sub_col_type>::t *,
348 typedef gen_sub_col_matrix_iterator<typename const_pointer<PT>::pointer,
351 typedef typename select_ref<abstract_null_type,
352 gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2>,
355 typedef typename linalg_traits<const_sub_col_type>::storage_type
357 typedef col_major sub_orientation;
358 typedef linalg_true index_sorted;
360 static size_type nrows(
const this_type &m) {
return m.nrows(); }
362 static size_type ncols(
const this_type &m) {
return m.ncols(); }
364 static const_sub_col_type col(
const const_col_iterator &it)
365 {
return const_sub_col_type(linalg_traits<M>::col(*it), it.si1); }
367 static sub_col_type col(
const col_iterator &it)
368 {
return sub_col_type(linalg_traits<M>::col(*it), it.si1); }
370 static const_col_iterator col_begin(
const this_type &m)
371 {
return const_col_iterator(m.begin_, m.si1, m.si2, 0); }
373 static col_iterator col_begin(this_type &m)
374 {
return col_iterator(m.begin_, m.si1, m.si2, 0); }
376 static const_col_iterator col_end(
const this_type &m)
377 {
return const_col_iterator(m.begin_, m.si1, m.si2, m.ncols()); }
379 static col_iterator col_end(this_type &m)
380 {
return col_iterator(m.begin_, m.si1, m.si2, m.ncols()); }
382 static origin_type* origin(this_type &v) {
return v.origin; }
384 static const origin_type* origin(
const this_type &v) {
return v.origin; }
386 static void do_clear(this_type &m) {
387 col_iterator it = mat_col_begin(m), ite = mat_col_end(m);
388 for (; it != ite; ++it)
clear(col(it));
391 static value_type access(
const const_col_iterator &itcol,
size_type i)
392 {
return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
394 static reference access(
const col_iterator &itcol,
size_type i)
395 {
return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
398 template <
typename PT,
typename SUBI1,
typename SUBI2>
399 std::ostream &operator <<(std::ostream &o,
400 const gen_sub_col_matrix<PT, SUBI1, SUBI2>& m)
401 { gmm::write(o,m);
return o; }
408 template <
typename PT,
typename SUBI1,
typename SUBI2,
typename ST>
409 struct sub_matrix_type_ {
410 typedef abstract_null_type return_type;
413 template <
typename PT,
typename SUBI1,
typename SUBI2>
414 struct sub_matrix_type_<PT, SUBI1, SUBI2, col_major>
415 {
typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> matrix_type; };
417 template <
typename PT,
typename SUBI1,
typename SUBI2>
418 struct sub_matrix_type_<PT, SUBI1, SUBI2, row_major>
419 {
typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> matrix_type; };
421 template <
typename PT,
typename SUBI1,
typename SUBI2>
422 struct sub_matrix_type {
423 typedef typename std::iterator_traits<PT>::value_type M;
424 typedef typename sub_matrix_type_<PT, SUBI1, SUBI2,
425 typename principal_orientation_type<
typename
426 linalg_traits<M>::sub_orientation>::potype>::matrix_type matrix_type;
429 template <
typename M,
typename SUBI1,
typename SUBI2>
inline
430 typename select_return
431 <
typename sub_matrix_type<const M *, SUBI1, SUBI2>::matrix_type,
432 typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
434 sub_matrix(M &m,
const SUBI1 &si1,
const SUBI2 &si2) {
435 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
436 "sub matrix too large");
438 typename select_return
439 <
typename sub_matrix_type<const M *, SUBI1,SUBI2>::matrix_type,
440 typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
441 M *>::return_type(linalg_cast(m), si1, si2);
444 template <
typename M,
typename SUBI1,
typename SUBI2>
inline
445 typename select_return
446 <
typename sub_matrix_type<const M *, SUBI1, SUBI2>::matrix_type,
447 typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
448 const M *>::return_type
449 sub_matrix(
const M &m,
const SUBI1 &si1,
const SUBI2 &si2) {
450 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
451 "sub matrix too large");
453 typename select_return
454 <
typename sub_matrix_type<const M *, SUBI1, SUBI2>::matrix_type,
455 typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
456 const M *>::return_type(linalg_cast(m), si1, si2);
459 template <
typename M,
typename SUBI1>
inline
460 typename select_return
461 <
typename sub_matrix_type<const M *, SUBI1, SUBI1>::matrix_type,
462 typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
464 sub_matrix(M &m,
const SUBI1 &si1) {
465 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
466 "sub matrix too large");
468 typename select_return
469 <
typename sub_matrix_type<const M *, SUBI1, SUBI1>::matrix_type,
470 typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
471 M *>::return_type(linalg_cast(m), si1, si1);
474 template <
typename M,
typename SUBI1>
inline
475 typename select_return
476 <
typename sub_matrix_type<const M *, SUBI1, SUBI1>::matrix_type,
477 typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
478 const M *>::return_type
479 sub_matrix(
const M &m,
const SUBI1 &si1) {
480 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
481 "sub matrix too large");
483 typename select_return
484 <
typename sub_matrix_type<const M *, SUBI1, SUBI1>::matrix_type,
485 typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
486 const M *>::return_type(linalg_cast(m), si1, si1);
void clear(L &l)
clear (fill with zeros) a vector or matrix.
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
size_t size_type
used as the common size type in the library