38 #ifndef GMM_SUB_MATRIX_H__
39 #define GMM_SUB_MATRIX_H__
49 template <
typename PT,
typename SUBI1,
typename SUBI2>
50 struct gen_sub_row_matrix {
51 typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
52 typedef typename std::iterator_traits<PT>::value_type M;
54 typedef typename std::iterator_traits<PT>::reference ref_M;
55 typedef typename select_ref<typename linalg_traits<M>
56 ::const_row_iterator,
typename linalg_traits<M>::row_iterator,
57 PT>::ref_type 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(
void)
const {
return si1.size(); }
70 size_type ncols(
void)
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 std::iterator_traits<PT>::value_type M;
85 typedef typename select_ref<typename linalg_traits<M>
86 ::const_row_iterator,
typename linalg_traits<M>::row_iterator,
88 typedef ITER value_type;
89 typedef ITER *pointer;
90 typedef ITER &reference;
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 ITER operator *()
const {
return it + si1.index(ii); }
114 ITER 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(
void) {}
123 gen_sub_row_matrix_iterator(
const
124 gen_sub_row_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
125 : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
126 gen_sub_row_matrix_iterator(
const ITER &iter,
const SUBI1 &s1,
128 : it(iter), si1(s1), si2(s2), ii(i) { }
132 template <
typename PT,
typename SUBI1,
typename SUBI2>
133 struct linalg_traits<gen_sub_row_matrix<PT, SUBI1, SUBI2> > {
134 typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
135 typedef typename std::iterator_traits<PT>::value_type M;
136 typedef typename which_reference<PT>::is_reference is_reference;
137 typedef abstract_matrix linalg_type;
138 typedef typename linalg_traits<M>::origin_type origin_type;
139 typedef typename select_ref<
const origin_type *, origin_type *,
140 PT>::ref_type porigin_type;
141 typedef typename linalg_traits<M>::value_type value_type;
142 typedef typename select_ref<value_type,
143 typename linalg_traits<M>::reference, PT>::ref_type reference;
144 typedef abstract_null_type sub_col_type;
145 typedef abstract_null_type col_iterator;
146 typedef abstract_null_type const_sub_col_type;
147 typedef abstract_null_type const_col_iterator;
148 typedef typename sub_vector_type<
const typename org_type<
typename
149 linalg_traits<M>::const_sub_row_type>::t *, SUBI2>::vector_type
151 typedef typename select_ref<abstract_null_type,
152 typename sub_vector_type<typename org_type<typename linalg_traits<M>::sub_row_type>::t *,
153 SUBI2>::vector_type, PT>::ref_type sub_row_type;
154 typedef gen_sub_row_matrix_iterator<typename const_pointer<PT>::pointer,
155 SUBI1, SUBI2> const_row_iterator;
156 typedef typename select_ref<abstract_null_type,
157 gen_sub_row_matrix_iterator<PT, SUBI1, SUBI2>, PT>::ref_type
159 typedef typename linalg_traits<const_sub_row_type>::storage_type
161 typedef row_major sub_orientation;
162 typedef linalg_true index_sorted;
163 static size_type nrows(
const this_type &m) {
return m.nrows(); }
164 static size_type ncols(
const this_type &m) {
return m.ncols(); }
165 static const_sub_row_type row(
const const_row_iterator &it)
166 {
return const_sub_row_type(linalg_traits<M>::row(*it), it.si2); }
167 static sub_row_type row(
const row_iterator &it)
168 {
return sub_row_type(linalg_traits<M>::row(*it), it.si2); }
169 static const_row_iterator row_begin(
const this_type &m)
170 {
return const_row_iterator(m.begin_, m.si1, m.si2, 0); }
171 static row_iterator row_begin(this_type &m)
172 {
return row_iterator(m.begin_, m.si1, m.si2, 0); }
173 static const_row_iterator row_end(
const this_type &m)
174 {
return const_row_iterator(m.begin_, m.si1, m.si2, m.nrows()); }
175 static row_iterator row_end(this_type &m)
176 {
return row_iterator(m.begin_, m.si1, m.si2, m.nrows()); }
177 static origin_type* origin(this_type &v) {
return v.origin; }
178 static const origin_type* origin(
const this_type &v) {
return v.origin; }
179 static void do_clear(this_type &m) {
180 row_iterator it = mat_row_begin(m), ite = mat_row_end(m);
181 for (; it != ite; ++it)
clear(row(it));
183 static value_type access(
const const_row_iterator &itrow,
size_type i)
184 {
return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
185 static reference access(
const row_iterator &itrow,
size_type i)
186 {
return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
189 template <
typename PT,
typename SUBI1,
typename SUBI2>
190 std::ostream &operator <<(std::ostream &o,
191 const gen_sub_row_matrix<PT, SUBI1, SUBI2>& m)
192 { gmm::write(o,m);
return o; }
199 template <
typename PT,
typename SUBI1,
typename SUBI2>
200 struct gen_sub_col_matrix {
201 typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
202 typedef typename std::iterator_traits<PT>::value_type M;
204 typedef typename std::iterator_traits<PT>::reference ref_M;
205 typedef typename select_ref<typename linalg_traits<M>
206 ::const_col_iterator,
typename linalg_traits<M>::col_iterator,
207 PT>::ref_type iterator;
208 typedef typename linalg_traits<this_type>::reference reference;
209 typedef typename linalg_traits<this_type>::porigin_type porigin_type;
217 {
return linalg_traits<M>::access(begin_ + si2.index(j), si1.index(i)); }
219 size_type nrows(
void)
const {
return si1.size(); }
220 size_type ncols(
void)
const {
return si2.size(); }
222 gen_sub_col_matrix(ref_M m,
const SUBI1 &s1,
const SUBI2 &s2)
223 : si1(s1), si2(s2), begin_(mat_col_begin(m)),
224 origin(linalg_origin(m)) {}
225 gen_sub_col_matrix() {}
226 gen_sub_col_matrix(
const gen_sub_col_matrix<CPT, SUBI1, SUBI2> &cr) :
227 si1(cr.si1), si2(cr.si2), begin_(cr.begin_),origin(cr.origin) {}
230 template <
typename PT,
typename SUBI1,
typename SUBI2>
231 struct gen_sub_col_matrix_iterator {
232 typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
233 typedef typename modifiable_pointer<PT>::pointer MPT;
234 typedef typename std::iterator_traits<PT>::value_type M;
235 typedef typename select_ref<typename linalg_traits<M>::const_col_iterator,
236 typename linalg_traits<M>::col_iterator,
238 typedef ITER value_type;
239 typedef ITER *pointer;
240 typedef ITER &reference;
241 typedef ptrdiff_t difference_type;
243 typedef std::random_access_iterator_tag iterator_category;
244 typedef gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2> iterator;
251 iterator operator ++(
int) { iterator tmp = *
this; ii++;
return tmp; }
252 iterator operator --(
int) { iterator tmp = *
this; ii--;
return tmp; }
253 iterator &operator ++() { ii++;
return *
this; }
254 iterator &operator --() { ii--;
return *
this; }
255 iterator &operator +=(difference_type i) { ii += i;
return *
this; }
256 iterator &operator -=(difference_type i) { ii -= i;
return *
this; }
258 { iterator itt = *
this;
return (itt += i); }
260 { iterator itt = *
this;
return (itt -= i); }
261 difference_type
operator -(
const iterator &i)
const {
return ii - i.ii; }
263 ITER operator *()
const {
return it + si2.index(ii); }
264 ITER operator [](
int i) {
return it + si2.index(ii+i); }
266 bool operator ==(
const iterator &i)
const {
return (ii == i.ii); }
267 bool operator !=(
const iterator &i)
const {
return !(i == *
this); }
268 bool operator < (
const iterator &i)
const {
return (ii < i.ii); }
269 bool operator > (
const iterator &i)
const {
return (ii > i.ii); }
270 bool operator >=(
const iterator &i)
const {
return (ii >= i.ii); }
272 gen_sub_col_matrix_iterator(
void) {}
273 gen_sub_col_matrix_iterator(
const
274 gen_sub_col_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
275 : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
276 gen_sub_col_matrix_iterator(
const ITER &iter,
const SUBI1 &s1,
278 : it(iter), si1(s1), si2(s2), ii(i) { }
281 template <
typename PT,
typename SUBI1,
typename SUBI2>
282 struct linalg_traits<gen_sub_col_matrix<PT, SUBI1, SUBI2> > {
283 typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
284 typedef typename std::iterator_traits<PT>::value_type M;
285 typedef typename linalg_traits<M>::origin_type origin_type;
286 typedef typename select_ref<
const origin_type *, origin_type *,
287 PT>::ref_type porigin_type;
288 typedef typename which_reference<PT>::is_reference is_reference;
289 typedef abstract_matrix linalg_type;
290 typedef typename linalg_traits<M>::value_type value_type;
291 typedef typename select_ref<value_type,
292 typename linalg_traits<M>::reference, PT>::ref_type reference;
293 typedef abstract_null_type sub_row_type;
294 typedef abstract_null_type row_iterator;
295 typedef abstract_null_type const_sub_row_type;
296 typedef abstract_null_type const_row_iterator;
297 typedef typename sub_vector_type<const typename org_type<typename linalg_traits<M>::const_sub_col_type>::t *, SUBI1>::vector_type const_sub_col_type;
298 typedef typename select_ref<abstract_null_type, typename sub_vector_type<typename org_type<typename linalg_traits<M>::sub_col_type>::t *, SUBI1>::vector_type, PT>::ref_type sub_col_type;
299 typedef gen_sub_col_matrix_iterator<typename const_pointer<PT>::pointer,
300 SUBI1, SUBI2> const_col_iterator;
301 typedef typename select_ref<abstract_null_type,
302 gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2>, PT>::ref_type
304 typedef col_major sub_orientation;
305 typedef linalg_true index_sorted;
306 typedef typename linalg_traits<const_sub_col_type>::storage_type
308 static size_type nrows(
const this_type &m) {
return m.nrows(); }
309 static size_type ncols(
const this_type &m) {
return m.ncols(); }
310 static const_sub_col_type col(
const const_col_iterator &it)
311 {
return const_sub_col_type(linalg_traits<M>::col(*it), it.si1); }
312 static sub_col_type col(
const col_iterator &it)
313 {
return sub_col_type(linalg_traits<M>::col(*it), it.si1); }
314 static const_col_iterator col_begin(
const this_type &m)
315 {
return const_col_iterator(m.begin_, m.si1, m.si2, 0); }
316 static col_iterator col_begin(this_type &m)
317 {
return col_iterator(m.begin_, m.si1, m.si2, 0); }
318 static const_col_iterator col_end(
const this_type &m)
319 {
return const_col_iterator(m.begin_, m.si1, m.si2, m.ncols()); }
320 static col_iterator col_end(this_type &m)
321 {
return col_iterator(m.begin_, m.si1, m.si2, m.ncols()); }
322 static origin_type* origin(this_type &v) {
return v.origin; }
323 static const origin_type* origin(
const this_type &v) {
return v.origin; }
324 static void do_clear(this_type &m) {
325 col_iterator it = mat_col_begin(m), ite = mat_col_end(m);
326 for (; it != ite; ++it)
clear(col(it));
328 static value_type access(
const const_col_iterator &itcol,
size_type i)
329 {
return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
330 static reference access(
const col_iterator &itcol,
size_type i)
331 {
return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
334 template <
typename PT,
typename SUBI1,
typename SUBI2> std::ostream &
operator <<
335 (std::ostream &o,
const gen_sub_col_matrix<PT, SUBI1, SUBI2>& m)
336 { gmm::write(o,m);
return o; }
342 template <
typename PT,
typename SUBI1,
typename SUBI2,
typename ST>
343 struct sub_matrix_type_ {
344 typedef abstract_null_type return_type;
346 template <
typename PT,
typename SUBI1,
typename SUBI2>
347 struct sub_matrix_type_<PT, SUBI1, SUBI2, col_major>
348 {
typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> matrix_type; };
349 template <
typename PT,
typename SUBI1,
typename SUBI2>
350 struct sub_matrix_type_<PT, SUBI1, SUBI2, row_major>
351 {
typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> matrix_type; };
352 template <
typename PT,
typename SUBI1,
typename SUBI2>
353 struct sub_matrix_type {
354 typedef typename std::iterator_traits<PT>::value_type M;
355 typedef typename sub_matrix_type_<PT, SUBI1, SUBI2,
356 typename principal_orientation_type<
typename
357 linalg_traits<M>::sub_orientation>::potype>::matrix_type matrix_type;
360 template <
typename M,
typename SUBI1,
typename SUBI2>
inline
361 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
362 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
364 sub_matrix(M &m,
const SUBI1 &si1,
const SUBI2 &si2) {
365 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
366 "sub matrix too large");
367 return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
368 SUBI2>::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI2>
369 ::matrix_type, M *>::return_type(linalg_cast(m), si1, si2);
372 template <
typename M,
typename SUBI1,
typename SUBI2>
inline
373 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
374 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
375 const M *>::return_type
376 sub_matrix(
const M &m,
const SUBI1 &si1,
const SUBI2 &si2) {
377 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
378 "sub matrix too large");
379 return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
380 SUBI2>::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI2>
381 ::matrix_type,
const M *>::return_type(linalg_cast(m), si1, si2);
384 template <
typename M,
typename SUBI1>
inline
385 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
386 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
388 sub_matrix(M &m,
const SUBI1 &si1) {
389 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
390 "sub matrix too large");
391 return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
392 SUBI1>::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>
393 ::matrix_type, M *>::return_type(linalg_cast(m), si1, si1);
396 template <
typename M,
typename SUBI1>
inline
397 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
398 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
399 const M *>::return_type
400 sub_matrix(
const M &m,
const SUBI1 &si1) {
401 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
402 "sub matrix too large");
403 return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
404 SUBI1>::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>
405 ::matrix_type,
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